Array in Bereiche aufteilen, struct vermeiden, aber wie

Gast #5776864
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?
Möchtest du die Array-Zellen in Bereiche einteilen, oder die Werte in 
dem Array?

Wenn ich deine doch ziemlich konfuse Beschreibung lese, dann solltest du 
besser dein eigentliches Problem und nicht deinen dir ausgedachten 
"Algorithmus" zur Lösung beschreiben.
Gast
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)
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
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
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)
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.
Gast
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
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] ...
Gast
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.
Gast
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
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
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.
Gast
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
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.
Gast
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
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.
Gast
&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
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.
Gast
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
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.