Hi!
Ich bin irgendwie zu blöd ein struct zu sortieren. :-(
Den ganzen Code habe ich angehängt. Hier ein bisl zur Erklärung:
1
structserv{
2
volatileuint8_tservo;
3
volatileintopen;
4
volatileintclosed;
5
volatileintposition;
6
volatileuint8_t*port;//Adresse des Ports
7
volatileuint8_tportbin;
8
}servos[SERVOANZAHL];
Bei volatile uint8_t *port; möchte ich gerne die Adresse des Ports
einlesen. Initialisiert wird das dann mit servos[0].port = &PORTD zum
Beispiel. Damit ich später mal mittels
*(servos[k].port) &= ~(servos[k].portbin);
den Entsprechenden Portbin auf High oder Low schalten kann.
Wenn ich jetzt das struct sortieren möchte nach dem Wert der bei
servos[k].position angegeben ist stellt es mich irgendwie auf.
Wahrscheinlich komme ich irgendwie mit den Pointern durcheinander oder
so?
Könnt ihr mir bitte helfen, ich komme einfach nicht drauf.
Danke
LG
Ernst
Ernst B. schrieb:> Wenn ich jetzt das struct sortieren möchte nach dem Wert der bei> servos[k].position angegeben ist stellt es mich irgendwie auf.
Wie sortierst du das Ganze denn ?
Verschiebst du die Informationen im Array herum ?
Wenn du noch genügend Platz hast, könntest du ein Pointer-Array
erstellen, dass auf diese serv-Elemente zeigt und nur die Pointer
sortieren. Das sollte auch wesentlich flotter von der Hand gehen.
Ernst B. schrieb:> Wenn ich jetzt das struct sortieren möchte
Meinst Du nicht vielleicht eher das Array? Eine Struktur kann man
ebensowenig sortieren wie man einen anderen Datentyp sortieren kann.
Dein Versuch über ein Bubblesort schlägt fehl, weil Du in "temp" nicht
ein Element des Arrays aufhebst, sondern nur einen Pointer darauf.
AVerr schrieb:> Struct-Zuweisungen funktionieren nicht immer so, wie du das> erwartest.>> sort[k] = sort[k-1];>> wird dir also nicht den struct im Array verschieben.
Seit C89 sind Strukturzuweisungen zulässig.
AVerr schrieb:> Ach, hatte deinen Anhang übersehen.>> Struct-Zuweisungen funktionieren nicht immer so, wie du das erwartest.
Doch das tun sie.
> wird dir also nicht den struct im Array verschieben. Du müsstest schon> jedes einzelne Feld im struct kopieren, also
Bloss nicht.
Dein Code:
1
voidBubble(structserv*sort,intelemente)
2
{
3
uint8_tk;
4
structserv*temp;
5
6
while(elemente--)
7
{
8
for(k=1;k<=elemente;k++)
9
{
10
if(sort[k-1].position>sort[k].position)
11
{
12
*temp=sort[k];
13
sort[k]=sort[k-1];
14
sort[k-1]=*temp;
15
16
}
17
}
18
}
Kurze schmerzlose Frage.
Wo genau ist denn der Speicher, auf den du hier einen Pointer erzeugt
hast
struct serv *temp;
und auf den du hier
*temp = sort[k];
eine komplette Struktur zwecks Zwischenspeicherung ablegen möchtest?
Nur weil du einen Pointer hast, heißt das noch lange nicht, dass du auch
den entsprechenden Speicher für die Daten hast, auf die ein Pointer
zeigen könnte.
Wie groß ist denn deine SERVOANZAHL ? Wird die noch wesentlich größer
als 8?
Lohnt es sich überhaupt, das vorzusortieren, bzw. für was brauchst du
die definierte Reihenfolge in dem Array?
Εrnst B✶ schrieb:> Wie groß ist denn deine SERVOANZAHL ? Wird die noch wesentlich größer> als 8?>> Lohnt es sich überhaupt, das vorzusortieren, bzw. für was brauchst du> die definierte Reihenfolge in dem Array?
Das war doch der Beitrag mit 1µs Genauigkeit für 9 Servos ohne
zeitlichen Versatz (also nicht sequentiell ein Servo nach dem anderen).
Eine vorgeschlagene Lösung benötigte dazu die sortierten Zeiten der PWM.
Nachtrag: der hier:
Beitrag "Newbie braucht Hilfe: 9 Servos mit 1µs Auflösung ansteuern? (AVR)"
Udo Schmitt schrieb:> Εrnst B✶ schrieb:>> Wie groß ist denn deine SERVOANZAHL ? Wird die noch wesentlich größer>> als 8?>>>> Lohnt es sich überhaupt, das vorzusortieren, bzw. für was brauchst du>> die definierte Reihenfolge in dem Array?>> Das war doch der Beitrag mit 1µs Genauigkeit für 9 Servos ohne> zeitlichen Versatz (also nicht sequentiell ein Servo nach dem anderen).> Eine vorgeschlagene Lösung benötigte dazu die sortierten Zeiten der PWM.> Nachtrag: der hier:> Beitrag "Newbie braucht Hilfe: 9 Servos mit 1µs Auflösung ansteuern? (AVR)"
Wobei ich auch dort nicht davon überzeugt bin, dass es notwendig ist ein
Servo 330 mal in der Sekunde upzudaten.
Ausserdem ist es eine GAAAAAAANZ schlechte Idee, wenn man sich diese
Daten durcheinandsortiert. Das macht dann das zuweisen von neuen Werten
so spannend, wenn man die Werte die zb aus der Mischerstufe
herauskommen, dann auch noch an die richtigen Servokanäle verteilen
will.
Aber vielleicht ist es ja auch nur eine Übung im behandeln von struct.
Karl Heinz Buchegger schrieb:> Wobei ich auch dort nicht davon überzeugt bin, dass es notwendig ist ein> Servo 330 mal in der Sekunde upzudaten.
Eben, wie groß sind denn bei Flugmodellen die Zeitkonstanten der
verschiedenen Bewegungen? Nimmt man einen kleinen Hubschrauber, dann sag
ich mal keine Zeitkonstante der Bewegungen in irgendeiner der 3 Achsen
ist kleiner als 1/10 Sekunde. Also macht es eigentlich keinen Sinn die
Abtastzeit der Regelung deutlich unter 1/50 Sekunde zu legen.
Damit handelt man sich doch nur wieder Probleme ein, daß sich I Anteile
zu weit aufintegrieren, D-Anteile zu schnell weg sind. Dann behilft man
sich wieder indem man die Eingangswerte künstlich verlangsamt indem man
gleitende Mittelwerte bildet etc.
Aber das hatten wir in dem Thread ja schon durchdiskutiert: Die Werbung
sagt die Servos können so viel auflösen und sind so schnell, also muss
es die erste Ansteuerung auch schon im allerersten Anlauf auch können
(sollen)
Man kann sich das Leben selbst schwer machen, aber man wächst ja mit
seinen Herausforderungen. Insofern: Viel Erfolg.
Karl Heinz Buchegger schrieb:> Wobei ich auch dort nicht davon überzeugt bin, dass es notwendig ist ein> Servo 330 mal in der Sekunde upzudaten.>> Ausserdem ist es eine GAAAAAAANZ schlechte Idee, wenn man sich diese> Daten durcheinandsortiert. Das macht dann das zuweisen von neuen Werten> so spannend, wenn man die Werte die zb aus der Mischerstufe> herauskommen, dann auch noch an die richtigen Servokanäle verteilen> will.>> Aber vielleicht ist es ja auch nur eine Übung im behandeln von struct.
Es ist beides. Das ganze Projekt ist eine Übung für mich. :-) Und es
macht halt mehr Spaß was zu üben wenn man auch ein gewisses Ziel
verfolgt.
Daß Du von den 330Hz nicht überzeugt bist habe ich eh gelesen. In dem
Projekt habe ich auch schon auf 50Hz umgestellt. Bleibe aber trotzdem
noch dabei alle Servos parallel anzusprechen und nicht seriell.
Neue Werte werden eigentlich nicht zugewiesen, die Werte werden
eingestellt und liegen im EEProm, so der Plan zumindest. Und von einer
Mischerstufe oder Fernbedienung kommen auch keine Werte die man
berücksichtigen muß. Außer f_status der peridisch abgefragt werden soll.
Aber das ist eigentlich eh nicht Thema sondern das sortieren des Structs
bzw. Arrays.
LG
Ernst
>> Kurze schmerzlose Frage.> Wo genau ist denn der Speicher, auf den du hier einen Pointer erzeugt> hast>> struct serv *temp;>> und auf den du hier>> *temp = sort[k];>> eine komplette Struktur zwecks Zwischenspeicherung ablegen möchtest?>> Nur weil du einen Pointer hast, heißt das noch lange nicht, dass du auch> den entsprechenden Speicher für die Daten hast, auf die ein Pointer> zeigen könnte.
Hallo Karl Heinz,
inzwischen sind die Fragen schon nimmer schmerzlos... :-)
Ich dachte eigentlich, durch die Referenz von struct serv ist die Größe
eigentlich klar. Aber scheinbar noch nicht wenn ich Deine Zeilen so
lese.
Heißt das, daß ich mittels
1
temp=malloc(sizeof(structserv*));
noch einen Speicher reservieren muß? Und muß ich den Speicher am Ende
der Funktion wieder freigeben?
LG und Danke
Ernst
Ich würde das nicht mit malloc machen, da fängtst du dir auf den kleinen
AVRs einen ganzen Rattenschwanz zusätzlicher Fehlerquellen ein.
Stattessen könntest du ein zweites "sortier-array" verwenden:
(ungetesteter Pseudo-Code)
die Servos bleiben so an Ort und Stelle, d.H. "servos[5]" verweist immer
auf das gleiche.
servos[reihenfolge[0]] bis servos[reihenfolge[8]] sind sortiert.
Rufus Τ. Firefly schrieb:> AVerr schrieb:>> Struct-Zuweisungen funktionieren nicht immer so, wie du das>> erwartest.>>>> sort[k] = sort[k-1];>>>> wird dir also nicht den struct im Array verschieben.>> Seit C89 sind Strukturzuweisungen zulässig.Karl Heinz Buchegger schrieb:> AVerr schrieb:>> wird dir also nicht den struct im Array verschieben. Du müsstest schon>> jedes einzelne Feld im struct kopieren, also>> Bloss nicht.>
Widersprechen sich diese beiden Beiträge? Aber wahrscheinlich verstehe
ich es nur nicht.
ist so eine Zuweisung
Ernst B. schrieb:> ist so eine Zuweisung> sort[k] = sort[k-1]> jetzt erlaubt oder nicht?
Probiers aus. Das Problem liegt eher hier:
> *temp = sort[k];
Wenn *temp "in den Void" zeigt.
dann lieber:
1
structservtemp;
2
...
3
4
temp=sort[k];
Wobei auch das bei deinen großzügig verteilten "volatiles" vermutlich
suboptimal ausgeführt werden wird. memcopy statt der Zuweisung umgeht
das.
Hier gleich vorneweg eine Warnung zum nächsten Fallstrick:
bei den "int"s (16 bit) in deiner Struct reicht das volatile alleine
nicht aus, damit du diese gleichzeitig gefahrlos in der ISR und im
Restprogramm verwenden kannst, zusätzlich müssen bei Zugriffen
ausserhalb der ISR auf diese Variablen die interrupts gesperrt werden.
Εrnst B✶ schrieb:> Ich würde das nicht mit malloc machen, da fängtst du dir auf den kleinen> AVRs einen ganzen Rattenschwanz zusätzlicher Fehlerquellen ein.>> Stattessen könntest du ein zweites "sortier-array" verwenden:>> (ungetesteter Pseudo-Code)>
1
>uint8_treihenfolge[9]={0,1,2,3,4,5,6,7,8};
2
>
3
>
4
>Bubble:
5
>...
6
>if(servos[reihenfolge[k-1]].position>
7
>servos[reihenfolge[k]].position){
8
>// Swape nur noch die indices!
9
>uint8_ttmp=reihenfolge[k];
10
>reihenfolge[k]=reihenfolge[k-1];
11
>reihenfolge[k-1]=tmp;
12
>}
13
>...
14
>
15
>
>> die Servos bleiben so an Ort und Stelle, d.H. "servos[5]" verweist immer> auf das gleiche.> servos[reihenfolge[0]] bis servos[reihenfolge[8]] sind sortiert.
Hallo doppelter Namensvetter! (Ist ja schon selten, daß noch jemand
Ernst heißt. Aber noch dazu den gleichen Buchstaben beim Nachnamen...)
Das ist auch eine lässige Idee. Ich sortiere dann nur noch das Array
reihenfolge[], richtig? Ist sicher eine praktikablere Lösung als das was
ich wollte. Ich kann auch die Servonummer im Struct weglassen wenn dann
servos[5] immer aufs gleiche verweist. (Wobei mir nicht klar ist wie
ich die Reihenfolge beim Debuggen kontrolliere, aber gut, das sehe ich
dann :-))
Neugierig wäre ich aber doch wie man das struct-Array von meiner
Ausgangsfrage sortiert? Muß ja auch irgendwie gehen.
LG
Ernst
Εrnst B✶ schrieb:> Hier gleich vorneweg eine Warnung zum nächsten Fallstrick:> bei den "int"s (16 bit) in deiner Struct reicht das volatile alleine> nicht aus, damit du diese gleichzeitig gefahrlos in der ISR und im> Restprogramm verwenden kannst, zusätzlich müssen bei Zugriffen> ausserhalb der ISR auf diese Variablen die interrupts gesperrt werden.
kurz eine Erklärung dazu: Da der AVR nur 8 Bit auf einmal verarbeitet
könnte zwischen den beiden Bytes (high und low) ein Interrupt kommen der
die Daten liest bzw. ändert, das ergibt dann Inkonsistenzen.
z.B. main: schreibt beide Bytes, tut irgendwas, schreibt neues low-Byte,
Interrupt
ISR: liest altes high-Byte und neues low-Byte -->bumm.
Fachbegriff imho "atomarer Zugriff".
struct schrieb:> Εrnst B✶ schrieb:>> Hier gleich vorneweg eine Warnung zum nächsten Fallstrick:>> bei den "int"s (16 bit) in deiner Struct reicht das volatile alleine>> nicht aus, damit du diese gleichzeitig gefahrlos in der ISR und im>> Restprogramm verwenden kannst, zusätzlich müssen bei Zugriffen>> ausserhalb der ISR auf diese Variablen die interrupts gesperrt werden.>> kurz eine Erklärung dazu: Da der AVR nur 8 Bit auf einmal verarbeitet> könnte zwischen den beiden Bytes (high und low) ein Interrupt kommen der> die Daten liest bzw. ändert, das ergibt dann Inkonsistenzen.>> z.B. main: schreibt beide Bytes, tut irgendwas, schreibt neues low-Byte,> Interrupt> ISR: liest altes high-Byte und neues low-Byte -->bumm.>> Fachbegriff imho "atomarer Zugriff".
Ich glaube, die volatile kann ich mir eh überall sparen bis auf den
Port-Zeiger. Der dürfte lt. Karl Heinz so definiert sein:
Karl Heinz Buchegger schrieb:> ein Port hat den Datentyp *(volatile unsigned char*)
Warum das aber ein char sein soll...?
In den FAQ steht: "...volatile teilt dem Compiler mit, dass ausnahmslos
alle Zugriffe auf eine Variable auch tatsächlich auszuführen sind und
keine Optimierungen gemacht werden dürfen, weil sich eine Variable auf
Wegen ändern kann, die für den Compiler prinzipiell nicht einsichtig
sind." Deshalb dachte ich, daß es eventuell Bröseln beim sortieren gibt.
Den Wert servos[].position werde ich in einer weiteren Routine
verändern. Aber keiner der Werte aus dem struct wird in einer ISR
verändert. Also nix was für den Compiler überraschend hinter seinem
Rücken passieren sollte. Ich schwitze allerdings immer davor, daß
irgendwas wegoptimiert wird. :-))
So, ich werde jetzt mal die einzelnen Vorschläge ausprobieren. :-D
>> Wobei auch das bei deinen großzügig verteilten "volatiles" vermutlich> suboptimal ausgeführt werden wird. memcopy statt der Zuweisung umgeht> das.
Was heißt "suboptimal" in dem Fall? Einfach "nur" langsam oder stellt es
mich mit dem Speicher irgendwann auf? (die Sortierungsroutine wird
häufig aufgerufen)
LG
Ernst
Rufus Τ. Firefly schrieb:> Ernst B. schrieb:>> Was heißt "suboptimal" in dem Fall?>> Langsam. Sehr langsam, im Vergleich zur Variante mit dem Pointerarray.
Dafür sind dann die Zugriffe in der sortierten Reihenfolge um einen Tick
schneller.
Man kann eben nicht alles haben.
Wichtig wär auch noch den Bubbelsort entweder durch etwas besseres zu
ersetzen oder dem einen vorzeitigen Abbruch zu erlauben wenn sich deine
Werte von einem Sortierlauf zum nächsten nur wenig ändern.
Karl Heinz Buchegger schrieb:> Rufus Τ. Firefly schrieb:>> Ernst B. schrieb:>>> Was heißt "suboptimal" in dem Fall?>>>> Langsam. Sehr langsam, im Vergleich zur Variante mit dem Pointerarray.>> Dafür sind dann die Zugriffe in der sortierten Reihenfolge um einen Tick> schneller.> Man kann eben nicht alles haben.
Wenn der Zugriff auf die sortierte Reihenfolge schneller ist, dann kommt
mir das eher gelegen als eine schnellere Sortierung. Ich greife ja dann
in einer ISR darauf zu und das ist das zeitkritischere.
>> Wichtig wär auch noch den Bubbelsort entweder durch etwas besseres zu> ersetzen
Was wäre denn schneller bzw. besser? Im Buch C von A bis Z schneidet bei
wenigen Elementen das Bubble-Sort sehr gut ab. Nur noch selection-Sort
ist einen Tick schneller. Vielleicht sollte ich das mal probieren.
> oder dem einen vorzeitigen Abbruch zu erlauben wenn sich deine> Werte von einem Sortierlauf zum nächsten nur wenig ändern.
Ich probiere lieber einen anderen Sortieralgorithmus denn dazu habe ich
keine Idee wie ich das anstelle.
Ich kämpfe eh gerade - nachdem das jetzt sortiert wird - damit, daß mein
Code, je nachdem ob ich mit den open oder closed Werten beginne,
funktioniert bzw. nicht funktioniert. Dem Code nach sollte es eigentlich
egal sein, ist es aber nicht. grml
@Rufus: Ich habe gerade gesehen, daß ich mich vorher verlesen habe.
Sorry. Habe ...seit C89 unzulässig... gelesen statt zulässig.
Ernst B. schrieb:>> oder dem einen vorzeitigen Abbruch zu erlauben wenn sich deine>> Werte von einem Sortierlauf zum nächsten nur wenig ändern.>> Ich probiere lieber einen anderen Sortieralgorithmus denn dazu habe ich> keine Idee wie ich das anstelle.
1
do {
2
sorted = true;
3
for( i = 0; i < NrElements - 1; ++i )
4
if( element[i] > element[i+1] ) {
5
tmp = element[i];
6
element[i] = element[i+1];
7
element[i+1] = tmp;
8
sorted = false;
9
}
10
}
11
} while( !sorted );
sobald bei einem Durchlauf durch die for Schleife festgestellt wird, das
alles sortiert ist, hört der Algorithmus auf. Wenn nur wenige
Vertauschungen notwendig sind (weil sich die Daten nur wenig verändert
haben), macht das einen Unterschied. Sind die Daten bereits sortiert
oder nahezu sortiert, dann ist das von keinem anderen Sortierverfahren
zu schlagen. Leider gibts den Fall nur selten. Deiner könnte aber so
einer sein.
cyblord ---- schrieb:> Bedenke das Ding läuft in O(n²)
Naja, N ist in dem Fall ja "9".
Also läufts in O(9^2) = O(81) = O(1)
;)
Scherz beiseite: Hier wird ja eine Datenstruktur benötigt, bei der der
"dringenste" Servo-Eintrag vorne liegt, eine komplette Sortierung ist
garnicht nötig.
daher: statt komplett sortieren vielleicht eine "priority queue"
einsetzen. Lässt sich schön innerhalb des Arrays (Binary Heap)
implementieren.
Entnehmen des "fälligen" Servos in der ISR als auch wieder-einfügen
eines Servos mit geänderter "position" gehen dann in O(log N).
cyblord ---- schrieb:> Das gute alte Bubblesort. Aber ob man dies wirklich produktiv einsetzen> sollte? Bedenke das Ding läuft in O(n²).
Das läuft in was? :-))
cyblord ---- schrieb:> Das gute alte Bubblesort. Aber ob man dies wirklich produktiv einsetzen> sollte? Bedenke das Ding läuft in O(n²).
Diese Variante allerdings nur im Worstcase.
Karl Heinz Buchegger schrieb:> cyblord ---- schrieb:>>>> Das gute alte Bubblesort. Aber ob man dies wirklich produktiv einsetzen>> sollte? Bedenke das Ding läuft in O(n²).>> Diese Variante allerdings nur im Worstcase.
Ändert nichts, die Laufzeit liegt in O(n²). Du kannst keine kleinere
obere Schranke angeben. Natürlich wird die reale Laufzeit einiges
darunter liegen, aber es geht ja darum wie schlimm es mit vielen
Elementen wird. Und mit BS wird es sehr schlimm.
Vergleiche hierzu QuickSort, hat ebenfalls im Worst-Case O(n²), arbeitet
jedoch unter Normalbedingungen in O(n*log(n)).
Wenn man auf der sicheren Seite sein will, sollte man sich mal
Intro-Sort angucken. Sortiert normalerweise mit Quicksort, erkennt aber
Partition-Elements welche in einem Teilarray eine Worst-Case Laufzeit
hervorrufen und fällt dann für diesen Teil auf Heap-Sort zurück. Sehr
effizient gelöst, alles in allem.
gruß cyblord
Εrnst B✶ schrieb:> Scherz beiseite: Hier wird ja eine Datenstruktur benötigt, bei der der> "dringenste" Servo-Eintrag vorne liegt, eine komplette Sortierung ist> garnicht nötig.
Ich bin in meinen Überlegungen eigentlich davon ausgegangen, daß ich
eine komplette Sortierung - zumindest der aktuellen bzw. nächsten
Positionswerte brauche.
Da ich die Werte ja nicht kenne kann es sein, daß - so wie bei meinen
Beispielwerten - einige Positionen sehr knapp oder gar genau gleich
sind. Die kann ich dann nicht mit dem OCR1B abfangen sondern muß über
die Differenz zum vorhergehenden Servo diese im selben ISR-Aufruf
abschalten. (Das ist IMHO der größte Schwachpunkt meiner Lösung. Ich
kann zwar 9 Servos anschließen, diese auch 1µs genau ansprechen. Aber
nicht, wenn zwei Werte sehr knapp nebeneinander liegen bzw. gleich
sind.)
Dazu habe ich jetzt noch ein Flag im Struct eingefügt auf das hin
untersucht wird.
Zwischen den Open und Closed werten muß auch noch eine Berechnung
stattfinden damit die Servos in der Verfahrensgeschwindigkeit
eingestellt werden können. Ich nähere mich also von der Open-Position zb
2000 langsam, zB in 10er Schritten der Closed-Position 4000. Da bleibt
die Liste - zumindest am Anfang - eigentlich sortiert. Deswegen scheint
mir so ein Abbruch der Sortierung eine gute Idee zu sein.
LG
Ernst
cyblord ---- schrieb:> Karl Heinz Buchegger schrieb:>> cyblord ---- schrieb:>>>>>>> Das gute alte Bubblesort. Aber ob man dies wirklich produktiv einsetzen>>> sollte? Bedenke das Ding läuft in O(n²).>>>> Diese Variante allerdings nur im Worstcase.>> Ändert nichts, die Laufzeit liegt in O(n²). Du kannst keine kleinere> obere Schranke angeben. Natürlich wird die reale Laufzeit einiges> darunter liegen, aber es geht ja darum wie schlimm es mit vielen> Elementen wird. Und mit BS wird es sehr schlimm.> Vergleiche hierzu QuickSort, hat ebenfalls im Worst-Case O(n²), arbeitet> jedoch unter Normalbedingungen in O(n*log(n)).
Genau.
Und wenn die Werte bereits nahezu sortiert vorliegen, ist BS nicht so
schlecht, bei geringem Aufwand. Und da es sich um Servowerte handelt,
die sich über die Zeit gesehen von einem Zeitschritt zum nächsten nur
wenig ändern, ist die Annahme, dass die Daten bereits nahezu sortiert
vorliegen, nicht von der Hand zu weisen.
Nichts anderes sag ich die ganze Zeit.
Du gehst immer vom allgemeinen Fall aus, ich hingegen versuch ein wenig
Wissen über die Daten mitzubenutzen.
Meine 'Verteidigung' ist keineswegs als allgemeine Empfehlung für BS zu
sehen! Bisher hatte ich nur 1 Fall, in dem BS tatsächlich (wegen seiner
Einfachheit und eben der nahezu Sortiertheit) die beste Lösung
darstellte. Ein Scan-Line Sweep Algorithmus, bei dem in jeder Scanline
Punkte sortiert werden müssen und die sich von einer Scanline zur
nächsten nur selten ändern. BS läuft dann in fast O(n), wobei der
konstante Anteil, der in der O Notation geflissentlich ignoriert wird
bei BS eben so klein ist, dass er O(log(n)) aussticht. O Notation ist
gut, wenn man auf große Zahlen extrapolieren muss. 9 Elemente in einem
Array sind aber nicht große Mengen.
Karl Heinz Buchegger schrieb:> Genau.> Und wenn die Werte bereits nahezu sortiert vorliegen, ist BS nicht so> schlecht, bei geringem Aufwand. Und da es sich um Servowerte handelt,> die sich über die Zeit gesehen von einem Zeitschritt zum nächsten nur> wenig ändern, ist die Annahme, dass die Daten bereits nahezu sortiert> vorliegen, nicht von der Hand zu weisen.
Stimmt.
>> Nichts anderes sag ich die ganze Zeit.
Ich weiß doch
>> Du gehst immer vom allgemeinen Fall aus, ich hingegen versuch ein wenig> Wissen über die Daten mitzubenutzen.
Da ist was drann. Vorallem weil wir ja hier, soweit ich sehe, ein
relativ kleines konstantes n haben.
Wenn man nicht selbst sortieren kann oder will, kann man im
alleräussersten Notfall ja noch auf die Standard-C-Bibliothek
zurückgreifen.
Da gibt es ein quick sort, das kaum zu toppen ist im allgemeinen Fall,
ausgetestet und kostenlos ist und nur mit einer passenden
Vergleichsfunktion aufgerufen werden muß (schließlich muß ja irgendwo
gesagt werden, anhand welchen Kriteriums sortiert werden soll).
Hi Karl Heinz,
warum hast Du da ein ++i und nicht ein i++?
Schreibe ich meine Schleifen bis jetzt falsch? :-/
Würde die Schleife bei einem i++ zwei mal i=0 durchlaufen werden? (Weil
ja postfix zuerst den "alten" Wert weitergibt und dann erst den
addierten?)
Oder beginnt Deine Schleife mit i=1? (Was ich mir nicht vorstellen kann,
Du wirkst sehr souverän in C auf mich)
Man sieht die For Schleifen aber so oft mit i++ statt ++i?
LG
Ernst
Ernst B. schrieb:> warum hast Du da ein ++i und nicht ein i++?
Ist an der Stelle völlig egal, die "Rückgabe" des Ausdrucks wird ja
nicht verwendet. Ist lediglich eine Frage des persönlichen Geschmacks.
Ernst B. schrieb:> warum hast Du da ein ++i und nicht ein i++?
C++ Gewohnheit.
In C ist es völlig wurscht, weil ++ sowieso nur auf integrale Typen
angewendet werden kann. In C++ kann es einen Unterschied in der Laufzeit
mchen, wenn die Laufvariable einen Datentyp hat, der Iterator Charakter
hat und die Pre und Post-fix ++ Operation implementier hat. In a
Nutshell: die Prefix Operation ++ kann man ohne Hilfsvariable
implementieren, die Postfix Version aber nicht. D.h. man hat eine
Objekterzeugung, die der Compiler mglw. nicht wegoptimieren kann.
Wie gesagt: Es ist einfach nur als eine von C++ herübertransportierte
Gewohnheit anzusehen, die in C keine Rolle spielt und an dieser Stelle
keinerlei funktionalen Unterschied mit sich bringt.