Hallo, ich würde gerne in einer C-Routine 6 unsigned 8-Bit-Zahlen miteinender vergleichen und herausfinden, welcher davon der größte ist. Das ganze sollte möglichst wenig Rechenaufwand aufweisen. Bin über Hilfe sehr dankbar ! Grüße Markus
hm, 8bit unsigned - was braucht man da über den Rechenaufwand nachdenken?
Das ganze sollte halt möglichst schnell abgearbeitet werden. (ca. 10us bei einem Takt von 16Mhz im ATMega168) Ich komme grade auf keinen sauberen Code, nur auf etliche if-Abfragen und Vergleichsoperationen.
Bei sowenig Werten ist nur der Vergleich von jedem Wert mit jedem anderen Wert effizient (wobei du doppelte Vergleiche natürlich ausschließen kannst, und die Sache ist transitiv). Du kannst auch einen Merge- oder Quicksort inplace implementieren, brauchst dann halt ein Array mit 6 Einträgen. Bucketsort lohnt bei 6 Werten nicht.
Jeder mit jedem? Wie wär's stattdessen mit einer Art "Mergesort für Arme"? a b c d e f \ / \ / \ / \ / \ / \ / max #define MAX2(x,y) ((x) > (y) ? (x):(y)) #define MAX3(x,y,z) MAX2(MAX2((x),(y)),MAX2((y),(z))) max = MAX3(MAX2(a, b), MA2X(c,d), MAX2(e,f)) 6 Vergleiche.
<pseudocode> zielwert=wert[1] for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break </pseudocode> danach hat zielwert den zahlenwert und a den index, maximal 5 vergleiche. Jochen Müller
@Jochen Ich fürchte, dass wird nicht klappen. Nimm dir mal ein Array [1,2,3,4,5,6]. Dann ist dein Ergebnis: Zielwert = 2, Index a=2 Das stimmt dann nur leider nicht... Brauchst du nur die Info welche Zahl die größte ist oder möchtest du auch wissen wo sie in deinem Array steht? gruß reiner
Hallo, wer n Zahlen auf die grösste untersuchen will muss nun mal alle in die Hand nehmen! Das ist doch offensichtlich!
>for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break
ohne break geht's besser,
immer genau 5 Vergleiche
max(a1,max(a2,max(a3,max(a4,...,max(an-1,an)...)
>>for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break >ohne break geht's besser, >immer genau 5 Vergleiche Und wenn man dann anstelle des Zahlenwertes einfach den Index a in Zielwert speichert, kennt man am Ende sowohl die größte Zahl als auch die Position im Array...
zielindex=1 for a=2 to 6 if wert[a]>wert[zielindex] dann zielindex=a
Jochen Müller schrieb: > <pseudocode> > zielwert=wert[1] > for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break > </pseudocode> Der break ist zuviel, sonst stimmts. Wenn es noch etwas schneller gehen soll, oder wenn die sechs Zahlen nicht in einem Array vorliegen, kann man die Schleife natürlich auch auseinanderrollen, so dass 5 If-Anweisungen dastehen. Das dürfte dann etwa 16 Zyklen, also 1 µs dauern.
Geht für Arrays der Länge 2(!)-255 byte i=sizeof(array)/sizeof(array[0])-1; //Länge des Arrays -1 max=array[0]; do { if (max<array[i] max=array[i]; } while (--i); //dekrement und anschließendes prüfen auf 0 //erzeugt am wenigsten "overhead" //in max steht das maximum
@Andreas Schwarz Jeden mit jedem unter Ausnutzung von Transitivität und Umkehrbarkeit ;) Transitiv: a>b, b>c => a>c Aber du hast natürlich recht, ich bin irgendwie von Sortieren ausgegangen, nicht von Maximum. War wohl etwas spät... In dem Fall reichen aber 5 Vergleiche: max=a; if(a<b) max=b; . . . ... und eine Zuweisung ;)
Also, Quicksort wäre sicherlich eine gute Lösung
Also es ist so: Ich habe einen Aray, werte[a;b;c;d;e;f]. Nun will ich die Stelle herauskriegen, an welcher der größte Wert steht. Dessen Betrag ist egal. Grüße
Ok, so sollte es recht zügig funktionieren: void CompIndukt(void) { extern uint16_t werte[]; extern uint8_t max; uint8_t index=0; uint16_t store=werte[0]; for (index=0;index<6;index++) { if(werte[index]>store) { store=werte[index]; max=index; } } } max gibt dann die Position der Größten Zahl im Aray an.
Wie wäre es damit:
1 | byte i=5; |
2 | byte max=5; |
3 | |
4 | do { |
5 | if (werte[max] < werte[i-1]) { |
6 | max = i-1; |
7 | }
|
8 | } while (--i); |
Nach Durchlauf steht max auf den Index des Array-Elements mit dem größten Wert. Gruß Christoph
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.