Vektor sortieren
-
Hallo!
Angenommen, ich will die ersten drei Elemente eines STL-Vektors sortieren. Dann geht das offenbar nicht mit
vector<int> vInts; sort(vInts.begin(),vInts.begin()+3);sondern braucht:
vector<int> vInts; vector<int>::iterator stop=vInts.begin(); advance(stop,3); sort(vInts.begin(),stop);Das funktioniert, aber gibts da eine schönere Lösung ähnlich dem oberen Zweizeiler?
lg
-
Warum sollte das erste nicht gehen?
-
drakon schrieb:
Warum sollte das erste nicht gehen?
Aufregend, jetzt gehts. Ich sitz wohl schon zu lange an der Tastatur heute, sorry.
-
Wozu ist das
advanceeigentlich gut? Ich wäre nie auf die Idee gekommen etwas anderes zu nutzen alsIterator + N.
-
Nick Unbekannt schrieb:
Wozu ist das
advanceeigentlich gut? Ich wäre nie auf die Idee gekommen etwas anderes zu nutzen alsIterator + N.Das brauchst Du bei einem Iterator ohne Random Access, etwa von einem Set. Dort müßest Du sonst sagen: for(unsigned i=0;i<3;++i) ++it;
lg
-
Hab ich ehrlich gesagt noch nie benötigt, ich mache meist nur Einer-Schritte, aber laut diesem Auszug von Stack-Overflow ist es auch bei einem Set so angedacht. Ich seh jetzt auch keinen Grund warum nicht. Auch kann ich mir nicht erklären, warum der Additions-Operator nicht einfach intern advance aufruft. Die Parameter sind doch bei beiden Aufrufen die gleichen?
http://stackoverflow.com/questions/671423/c-stl-vectors-get-iterator-from-index
-
std::advancebrauchst du, wenn du unabhängig vom Iterator Typ, generisch inkrementieren willst. Bei einer Liste braucht das O(n) und bei einemstd::vectorgeht das dann in O(1).typedef std::vector<int> my_list; //... void foo() { my_list l; //... my_list::iterator it = l.begin(); std::advance(it,5); }und irgendwann merkst du, dass da besser doch eine
listund keinvectorwäre und dann musst du nur eine Zeile ändern (die mit dem typedef). Ansonsten müsstest du das inkrement um 5 in einer loop machen.Man hätte natürlich das auch gleich im +-Operator implementieren können. Ich weiss nicht warum sie das so gemacht haben, aber ich finde es so auch natürlicher, weil sonst ein vermeindliche Addition plötzlich eben doch recht teuer wird und man merkt es gar nicht.
-
Nick Unbekannt schrieb:
Hab ich ehrlich gesagt noch nie benötigt, ich mache meist nur Einer-Schritte, aber laut diesem Auszug von Stack-Overflow ist es auch bei einem Set so angedacht. Ich seh jetzt auch keinen Grund warum nicht. Auch kann ich mir nicht erklären, warum der Additions-Operator nicht einfach intern advance aufruft. Die Parameter sind doch bei beiden Aufrufen die gleichen?
http://stackoverflow.com/questions/671423/c-stl-vectors-get-iterator-from-index
Die STL folgt weitgehend dem Prinzip dass es für Dinge die "billig" sind "direkte" Funktionen/Operatoren gibt, und für Dinge die "teuer" sind nix bzw. Hilfsfunktionen.
Beispielsweise hat ein "std::vector" kein "push_front", obwohl man es problemlos machen kann (über "insert" halt). Nur ist es "teuer", und deswegen gibt's die "direkte" Funktion "push_front" eben nicht.
Ob es "+" für Iteratoren gibt folgt dem selben Prinzip.
Bei Random-Access Operatoren ist "+" billig, also gibt es "+".
Und für Nicht-Random-Access Operatoren gibt es "advance".Das schöne daran ist, dass man "advance" auch z.B. in Templates bedenkenlos verwenden kann, weil es entsprechend spezialisiert ist.
D.h. für Random-Access Operatoren wird nicht sinnloser Weise in einer Schleife "++" aufgerufen.Der Hintergedanke ist vermutlich: wenn etwas einfach geht, macht man es einfach, ohne weiter darüber nachzudenken. Bei "billigen" Operationen ist das auch OK. Daher sollten "billige" Operationen einfach sein - weil warum unnötig kompliziert.
Und wenn etwas doch "unnötig" kompliziert ist, dann fragt man sich hoffentlich warum. Wenn man dann nachforscht kommt man drauf dass es kompliziert ist, weil es eben nicht "billig" ist. Bzw. wenn man bereits weiss warum, wird man hoffentlich aufmerksam, und überlegt sich ob man das Problem nicht anders lösen kann, mit einfacheren und "billigeren" Operationen.
Ist IMO ziemlich logisch.