Array in Bereiche aufteilen, struct vermeiden, aber wie

Gast #5776864
Lesenswert?

Hallo

Mir steht ein Array zur Verfügung. Dieser beinhaltet verschiedene Werte.
Wenn dieses Array eine bestimmtle Länge hat, möchte ich dieses in 10 
etwa gleich grosse Bereiche einteilen. Sagen wird 10 Bereiche.

also Bereich 1 Index 0-9
Berech 2 Index 10-19 etc. etc.

Jetzt möchte ich aber beim Zugriff auf die Bereiche sagen können:

if ((wert < bereich5.obereGrenze) && (wert > bereich5.untereGrenze))

damit ich gleich sehe, was damit gemeint ist.

Da komme ich um ein struct nicht herum oder? Mit Arrays geht das ja 
nicht.
Oder ist das anders möglich dies zu bewerkstelligen?
Persönliche Seite #5777121
Lesenswert?

Hans schrieb:
> da1l6 schrieb:
>> Hallo,
>>
>> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>>
>> da1l6
>
>
> Was für ein freundliches Forum. Hier ist man wohl gleich als Genies zur
> Welt gekommen und alles gleich vom Himmel gefallen.
> Danke trotzdem

Das nicht, aber eine ausreichende Fähigkeit zum strukturierten Denken 
war eigentlich doch immer vorhanden.
Und bei deiner Aufgabenstellung hätte ich auch lieber das ursprüngliche 
Problem zurück...
WARUM ZUR HÖLLE willst du das Array unterteilen? Gibt es dafür 
irgendeinen nachvollziehbaren Grund?
(Firma: EleLa - www.elela.de) #5777136
Lesenswert?

Man kann z.B. eine Struktur schaffen

typedef struct
{
uint8 Wert1;
uint16 Wert2;
uint32 Wert3;
uint8 DummeZumAuffüllenAuf10Byte;
} st1;

Diese dann mit einem Array überlagern

union
{
  uint8 werte[100];
  st1 Strcturwerte[10];
} u1;

Zugriff wäre dann
u1.werte[0];
u1.Strcturwerte[1].Wert2;

Damit kann man auf die Daten roh zugreifen und per Struktur auf die 
Werte. Syntaktisch ist das vermutlich grad nicht ganz richtig, das wirst 
du schon selbst hin bekommen.
Gast #5777151
Lesenswert?

Tim T. schrieb:
> Hans schrieb:
>> da1l6 schrieb:
>>> Hallo,
>>>
>>> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>>>
>>> da1l6
>>
>>
>> Was für ein freundliches Forum. Hier ist man wohl gleich als Genies zur
>> Welt gekommen und alles gleich vom Himmel gefallen.
>> Danke trotzdem
>
> Das nicht, aber eine ausreichende Fähigkeit zum strukturierten Denken
> war eigentlich doch immer vorhanden.
> Und bei deiner Aufgabenstellung hätte ich auch lieber das ursprüngliche
> Problem zurück...
> WARUM ZUR HÖLLE willst du das Array unterteilen? Gibt es dafür
> irgendeinen nachvollziehbaren Grund?

Ich habe in 2 verschiedenen Arrays Werte zweier Graphen gespeichert.
Die Kurven sehen zB so wie oben im Bild aus. Zb zwischen den Werten 10 
und 20 soll etwas passieren. Zwischen anderen etwas Anderes. Die genaue 
Einteilung ist mir überlassen.
Ich nutze ein drittes Array worin ich die Indizes festhalte, damit ich 
sie nicht jedes Mal berechnen muss. Zum Beispiel Bereich 1 Index 10 -15. 
Bereich 2 21-32 etc.
Im Array dann zB {0, 5, 10, 15, 20, 25...} kann ich dann auf die 
Grenzwerte zugreifen, anstatt jedes Mal den Index für den Grenzwert zu 
berechnen. Bereich 1 wäre so nun Index 0 bis 1, Bereich 2 Index 10 bis 
15.
Das funktioniert zwar, aber ich müsste dann wie folgt arbeiten, wenn ich 
die Werte zweier Arrays auswerten möchte:

if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) && 
(wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )

Versteht ihr jetzt?
Auf diese Weise sehe ich nicht auf Anhieb, dass es Bereich 1 ist, nur 
daran, dass die Indizes 0 und 1 sind. Wie macht man es in der Praxis?
Angehängte Dateien:
Gast #5777154
Lesenswert?

Hans schrieb:

>
> Ich habe in 2 verschiedenen Arrays Werte zweier Graphen gespeichert.
> Die Kurven sehen zB so wie oben im Bild aus. Zb zwischen den Werten 10
> und 20 soll etwas passieren. Zwischen anderen etwas Anderes. Die genaue
> Einteilung ist mir überlassen.
> Ich nutze ein drittes Array worin ich die Indizes festhalte, damit ich
> sie nicht jedes Mal berechnen muss.
> Im Array dann zB {0, 5, 10, 15, 20, 25...} kann ich dann auf die
> Grenzwerte zugreifen, anstatt jedes Mal den Index für den Grenzwert zu
> berechnen. Bereich 1 wäre so nun Index 0 bis 1, Bereich 2 Index 10 bis
> 15.
> Das funktioniert zwar, aber ich müsste dann wie folgt arbeiten, wenn ich
> die Werte zweier Arrays auswerten möchte:
>
> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )
>
> Versteht ihr jetzt?
> Auf diese Weise sehe ich nicht auf Anhieb, dass es Bereich 1 ist, nur
> daran, dass die Indizes 0 und 1 sind. Wie macht man es in der Praxis?

So sollte es besser verständlich sein
(Firma: EleLa - www.elela.de) #5777174
Lesenswert?

Ich habe es zwar immer noch nicht so recht verstanden, das könnte ein 
Lösungsansatz sein:

Um schneller was zu errechnen und wenn das Array nicht mehr als 64 
Elemente hat könnte man sich eine Variable mit uint64_t anlegen. Jedes 
mal wenn das Ergebnis zutrifft setzt man da ein Bit, da dieser Typ 64 
Bits hat kann man somit Array Element [0] .. [63] jeweils ein Bit 
zuordnen.
Dann braucht man nur noch die Bits shiften/ausmaskieren um die Position 
zu finden.
Persönliche Seite #5777186
Lesenswert?

So langsam dämmert es. Also die Grundeigenschaft eines Bereiches ist das 
er sich durch zwei Positionen beschreiben lässt, Anfang und Ende. Ich 
würde dementsprechend diese zwei Informationen paarweise speichern, also 
eine Liste mit den zwei Indizes pro Knoten. Zum durchgehen der Bereiche 
musst du dann nur prüfen ob der Wert an der Stelle des zweiten Index 
größer als dein gesuchter Wert ist, wenn ja bist du im richtigen 
Bereich, wenn nicht zum nächsten Knoten und erneut prüfen.
Gast #5777208
Lesenswert?

A. S. schrieb:
> Hans schrieb:
>> Da komme ich um ein struct nicht herum oder?
>
> Ja, ein struct, dass zwei integer enthält, begin und end.
>
> Und von diesem struct dann ein Array, so viele Bereiche Du willst, z.b.
> 8
>
> struct sBereichsPtr B[8];
>
> if wert2>Array[B[2].begin] ...

Danke für den Tipp

Stefanus F. schrieb:
> Tim T. schrieb:
>> zwei Positionen beschreiben lässt, Anfang und Ende
>
> Rate mal, was ein Pointer ist, bzw. wie man das Dingsbums nennt, das
> sich zwischen zwei Pointern erstreckt.

Wie würde man es mit Pointern machen?
Was meinst du mit dem Dingsbums zwischen 2 Pointern?
Da ist irgend einer Wert bestimmter Grösse zB 1 oder 2 Byte.
Dingsbums wäre dann also 1 oder 2 Byte.
Persönliche Seite #5777211
Lesenswert?

Stefanus F. schrieb:
> Tim T. schrieb:
>> zwei Positionen beschreiben lässt, Anfang und Ende
>
> Rate mal, was ein Pointer ist, bzw. wie man das Dingsbums nennt, das
> sich zwischen zwei Pointern erstreckt.

Du bist ja ein ganz schlauer.
Und falls du noch mehr Schlaubischlumpf Wissen anbringen willst, köntest 
du mir noch erzählen das der Arrayindex ein Offset relativ zur 
Speicheradresse des ersten Arrayelementes ist, multipliziert mit der 
Elementgröße...
Gast #5777214
Lesenswert?

da1l6 schrieb:
> Hallo,
>
> klingt für mich nach einem Fall von XY-Problem: http://xyproblem.info
>
> da1l6

Max Kanat-Alexander:

> If somebody comes up to you and says something like, “How do I make this pony 
fly to the moon?”, the question you need to ask is, “What problem are you trying 
to solve?” You’ll find out that they really need to collect gray rocks. Why they 
thought they had to fly to the moon, and use a pony to do it, only they know. 
People do get confused like this.
Gast #5777215
Lesenswert?

Hans schrieb:
> Wie würde man es mit Pointern machen?
> Was meinst du mit dem Dingsbums zwischen 2 Pointern?

Mit zwei Pointern beschreibst du einen Bereich im Speicher (Anfang und 
Ende).

Ich weiß, dass manche Leute Pointer eklig finden, aber C Entwickler 
müssen damit klar kommen. Ich finde auch Wasser eklig und doch kann ich 
den Kontakt damit nicht ganz vermeiden.
Persönliche Seite #5777219
Lesenswert?

Stefanus F. schrieb:
> Hans schrieb:
>> Wie würde man es mit Pointern machen?
>> Was meinst du mit dem Dingsbums zwischen 2 Pointern?
>
> Mit zwei Pointern beschreibst du einen Bereich im Speicher (Anfang und
> Ende).
>
> Ich weiß, dass manche Leute Pointer eklig finden, aber C Entwickler
> müssen damit klar kommen. Ich finde auch Wasser eklig und doch kann ich
> den Kontakt damit nicht ganz vermeiden.

Und bringt hier keinerlei Vorteile, ob er sich nun jeweils den Index der 
Anfangs und End Arrayelemente merkt oder die Speicheradresse der beiden 
Elemente, ist hierbei total egal.
Gast #5777235
Lesenswert?

Stefanus F. schrieb:
> Tim T. schrieb:
> Und bringt hier keinerlei Vorteile, ob er sich nun jeweils den Index der
> Anfangs und End Arrayelemente merkt oder die Speicheradresse der beiden
> Elemente, ist hierbei total egal.
>
> Ja, kann man so sehen. Für mich wäre die Nutzung von Pointern einfacher.
> Aber ich bin ja nicht jeder.

Könntest du mal win bsp geben?
Gast #5777256
Lesenswert?

Ok, einen kleines Beispiel gebe ich Dir:
1
#include <stdio.h>
2
#include <string.h>
3

4
void ausgeben(char* von, char* bis)
5
{
6
    while (von<bis)
7
    {
8
        putchar(*von);
9
        von++;
10
    }
11
}
12

13
int main()
14
{
15
    char text[]="Das ist ein Array, gefüllt mit Zeichen";
16
    
17
    char gesucht[]="ein Array";
18
    char* start=strstr(text,gesucht); 
19
    char* ende=start+strlen(gesucht);
20
    
21
    ausgeben(start,ende);
22
}

Das Schöne an der Funktion ausgeben() ist, dass die keine Ahnung haben 
muss, was sie ausgeben soll. Es muss nicht unbedingt ein Text in diesem 
einen Array sein. Der Text könnte auch ganz woanders stehen.

Zahlreiche Funktionen aus der Standard C Binbliothek machen es etwas 
anders: Sie erwarten einen Zeiger auf den Anfang und dann einen Integer, 
der die Länge angibt.
Persönliche Seite #5777260
Lesenswert?

&array[4] ist z.B. die Speicheradresse des fünften Wertes, &array[9] die 
des zehnten. Wenn du dir jetzt den Bereich merken willst, kannst du also 
entweder die Indexe 4 und 9 speichern oder die jeweiligen 
Speicheradressen (&array[4] und &array[9]).
Aber zugeben ich bin auch nicht wirklich motiviert dir das jetzt alles 
vorzukauen.
Gast #5777291
Lesenswert?

Tim T. schrieb:
> &array[4] ist z.B. die Speicheradresse des fünften Wertes,
> &array[9] die des zehnten. Wenn du dir jetzt den Bereich merken willst,
> kannst du also entweder die Indexe 4 und 9 speichern oder die jeweiligen
> Speicheradressen (&array[4] und &array[9]).
> Aber zugeben ich bin auch nicht wirklich motiviert dir das jetzt alles
> vorzukauen.

schon verstanden, danke
Gast #5777299
Lesenswert?

Wenn die Werte in einem Array liegen und aufsteigend sortiert sind, dann 
wäre vielleich so etwas eine Möglichkeit? (einfach Intervallgrenzen in 
einem zweidim. Array ablegen)
1
    //Anzahl der Unterteilungen (Bereiche)
2
    #define ANZ_BER 5
3
    
4
    int arr[]={
5
                1,3, //Bereich 1
6
                4,6,7,8,11, //Bereich 2
7
                13,15,16,18,21,23,26,//Bereich 3
8
                29,32,37,42, //Bereich 4
9
                47,49 //Bereich 5
10
            };
11
    
12
    int indizes[ANZ_BER][2]={
13
                                {0,1},  // linke u. rechte Indizes fuer Bereich 1
14
                                {2,6},  // -||- fuer Bereich 2 
15
                                {7,13}, //usw.
16
                                {14,17},
17
                                {18,19}
18
                            };
19
    
20
    int aktueller_wert=39;
21

22
    for(int i=0; i<ANZ_BER; i++){
23
        
24
        if(aktueller_wert>=arr[indizes[i][0]] && aktueller_wert<=arr[indizes[i][1]]){
25
            printf("%d liegt im Bereich %d\n", aktueller_wert, i+1);
26
        }   
27
    
28
    }
Gast #5777326
Lesenswert?

zitter_ned_aso schrieb:
> Hans schrieb:
>> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
>> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )
>
> Laut deiner Skizze liefern die Funktionen steigende / fallende Werte. Du
> prüfst aber so als würden beide Funkionen steigende Werte liefern.

wenn "graph1" rot ist (siehe Skizze), dann solltest du das anders 
testen.
1
if( ((wert1 <= graph1[iArray[0]]) && (wert1 > graph1[iArray[1]])) usw...


Das habe ich gemeint.

Die Funktionswerte von "graph1" (rot) werden ja kleiner.
Gast #5777341
Lesenswert?

zitter_ned_aso schrieb:
> Wenn die Werte in einem Array liegen und aufsteigend sortiert
> sind, dann wäre vielleich so etwas eine Möglichkeit? (einfach
> Intervallgrenzen in einem zweidim. Array ablegen)    //Anzahl der
> Unterteilungen (Bereiche)
>     #define ANZ_BER 5
>
>     int arr[]={
>                 1,3, //Bereich 1
>                 4,6,7,8,11, //Bereich 2
>                 13,15,16,18,21,23,26,//Bereich 3
>                 29,32,37,42, //Bereich 4
>                 47,49 //Bereich 5
>             };
>
>     int indizes[ANZ_BER][2]={
>                                 {0,1},  // linke u. rechte Indizes fuer
> Bereich 1
>                                 {2,6},  // -||- fuer Bereich 2
>                                 {7,13}, //usw.
>                                 {14,17},
>                                 {18,19}
>                             };
>
>     int aktueller_wert=39;
>
>     for(int i=0; i<ANZ_BER; i++){
>
>         if(aktueller_wert>=arr[indizes[i][0]] &&
> aktueller_wert<=arr[indizes[i][1]]){
>             printf("%d liegt im Bereich %d\n", aktueller_wert, i+1);
>         }
>
>     }

Die Werte der Graphen können sich bei mir immer leicht ändern.
Das iwo so das Problem. So müsste ich viel zu viel anpasse. Sortiert 
sind sie auch nicht. kann sein dass 2 oder 3 werte hintereinander die 
gleichen sind aber der andere graph die gleichrn indizes betreffend sich 
ändern können.

daher möchte ich die werte in den arrays möglichst nicht anfassen müssen

zitter_ned_aso schrieb:
> zitter_ned_aso schrieb:
> Hans schrieb:
> if( ((wert1 >= graph1[iArray[0]]) && (wert1< graph1[iArray[1]])) &&
> (wert2 >= graph2[iArray[0]]) && (wert2< graph2[iArray[1]])) )
>
> Laut deiner Skizze liefern die Funktionen steigende / fallende Werte. Du
> prüfst aber so als würden beide Funkionen steigende Werte liefern.
>
> wenn "graph1" rot ist (siehe Skizze), dann solltest du das anders
> testen.if( ((wert1 <= graph1[iArray[0]]) && (wert1 > graph1[iArray[1]]))
> usw...
>
> Das habe ich gemeint.
> Die Funktionswerte von "graph1" (rot) werden ja kleiner.

ach das meinst du
darauf habe ich beim erklären gar nicht geachtet, weil ich noch gar 
nicht so weit bin
#5777374
Lesenswert?

Stefanus F. schrieb:
> Mit zwei Pointern beschreibst du einen Bereich im Speicher (Anfang und
> Ende).

Stefanus F. schrieb:
> Zahlreiche Funktionen aus der Standard C Bibliothek machen es etwas
> anders: Sie erwarten einen Zeiger auf den Anfang und dann einen Integer,
> der die Länge angibt.

Die Lösung mit zwei Pointern bevorzuge ich auch, um einen Pufferbereich 
zu beschreiben. Denn der Endpointer bleibt beim Schreiben in einen 
Puffer immer gleich, während die Länge des noch freien Bereichs immer 
neu berechnet werden muss.

Die Standard C Bibliothek ist in mancher Hinsicht nicht optimal.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren