Vector sortieren mit zwei Kriterien
-
Hallo Leute,
mal ne Frage zum sortieren eines Vector von Strukturen.
Wenn ich jetzt zum Beilpiel sowas habe:
struct test { int p; string name; bool operator () (const test& a, const test& b) { //return(a.p < b.p && a.name < b.name ) return (a.p< b.p); } };
Sortieren nach p einzeln mittels std::sort ist ja kein problem oder nur nach name.
Aber wie mache ich des, wenn ich nach beiden Kriterien sortieren möchte erst
nach p und dann nach name, aber ohne das die sortierung von name die Sortierung von p umschmeisst.
-
Verwende einen stabilen Sortieralgorithmus.
-
Was heistt das im Details...
Könntest Du mir mal ein Beispiel geben??
-
Mit einem stabilen Sortieralgorithmus müsste man zweimal sortieren.
So ist's besser:
bool operator () (const test& a, const test& b) { if(a.p != b.p) return a.p < b.p; return a.name < b.name; }
-
So was?
bool operator () (const test& a, const test& b) { //return(a.p < b.p && a.name < b.name ) // return (a.p< b.p); return a.p == b.p ? a.name < b.name : a.p < b.p; }
-
Ups, hab deinen Beitrag nicht richtig durchgelesen bzw. nur den Text gelesen, ohne den Quelltext zu beachten. Du willst ja den Operator erstellen.
Dann musst du die Fallunterscheidung machen, und zusätzlich angeben, was bei Gleichheit des ersten Sortierkriteriums geschehen soll. Steht aber inzwischen ja schon 2x da.
-
@MFK ist der Algorithmus jetzt limitiert auf zwei Kriterien oder kann mann da jetzt mehrere Kriterien anfügen.
-
ismaild schrieb:
@MFK ist der Algorithmus jetzt limitiert auf zwei Kriterien oder kann mann da jetzt mehrere Kriterien anfügen.
Komische Frage. Du wolltest 2 Kriterien, die hast du jetzt. Wenn du noch mehr willst, musst du die halt logisch unterbringen.
Aber prinzipiell: Ja, du kannst beliebig viele Kriterien unterbringen.
-
Ok wenn ich das richtig verstanden habe sieht es bei drei Kriterien so aus:
bool operator () (const test& a, const test& b) { if(a.p != b.p) return a.p < b.p; return a.name < b.name; return a.vorname < a.vorname; }
Aber was ich net verstehe wieso wird nur bei p auf gleichheit geprüft und nicht bei
name???
-
ismaild schrieb:
Ok wenn ich das richtig verstanden habe sieht es bei drei Kriterien so aus:
Nö.
ismaild schrieb:
Aber was ich net verstehe wieso wird nur bei p auf gleichheit geprüft und nicht bei
name???Genau das ist falsch. Nur beim letzten Kriterium brauchst du nicht auf Ungleichheit zu prüfen.
-
Du solltest eigentlich sehen das 3. nie stattfinden KANN
bool operator () (const test& a, const test& b) { if(a.p != b.p) return a.p < b.p; // 1. return a.name < b.name; // 2. return a.vorname < a.vorname; //3. }
daher
bool operator () (const test& a, const test& b) { if(a.p != b.p) return a.p < b.p; // 1. if (a.name != b.name) return a.name < b.name; // 2. return a.vorname < a.vorname; //3. }
Eventuell mag es sogar sinnvoll sein name und vorname vorher durch toLower() zu schicken um typos auszumerzen ... sonst ist xaver immer kleiner als Abel
-
Ok jetzt habe ich verstanden, also mit copy und paste komme ich net weiter deswegene habe ich nochmal nachgefragt und danke Euch recht herzlich dafür..
-
padreigh schrieb:
sonst ist xaver immer kleiner als Abel
Andersrum.
-
Dein Sortierkriterium muss Strict Weak Ordering erfüllen.
Und um mehrere Kriterien einfach zu sortieren, gibt es ein nettes kleines Template in der Standardbibliothek:
std::make_pair(a.p, a.name) < std::make_pair(b.p, b.name);
Oder generell
std::pair
aus<utility>
. Und das kannst du auch verschachteln. In Zukunft wird die Verschachtelung mitstd::tuple
nicht mehr nötig sein.