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.
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
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?
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.
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?
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
Hans schrieb:> Wie macht man es in der Praxis?
In meiner Praxis macht man es so, dass der nächste Patient aufgerufen
wird, und dann auch "dranne" kommt.
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.
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.
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.
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] ...
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.
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...
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.
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.
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.
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.
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?
chartext[]="Das ist ein Array, gefüllt mit Zeichen";
16
17
chargesucht[]="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.
&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.
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.
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
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)
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.
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.