Was ist der einfachste Weg, lexikographischen Vergleich für Elemente einer Klasse definieren?
-
21-09-2019 - |
Frage
Wenn ich eine Klasse, dass ich zu sortieren können, wollen (dh unterstützen eine weniger-als-Konzept), und es hat mehrere Datenelemente, so dass ich dann lexikographische Ordnung muss ich so etwas wie dieses brauchen:
struct MyData {
string surname;
string forename;
bool operator<(const MyData& other) const {
return surname < other.surname || (surname==other.surname && forename < other.forename); }
};
Das wird ziemlich unhandlich für alles, was mit mehr als 2 Datenelementen. Gibt es einfachere Möglichkeiten, es zu erreichen? Die Datenelemente jede Vergleichbare Klasse sein können.
Lösung 2
Andere Tipps
tuple
ist eine gute Idee, aber wenn Sie behalten möchten, Namen für die Elementvariablen mit, könnte es gut genug sein, um die Umstrukturierung Ihrer Vergleichsfunktion wie folgt aus:
struct MyData {
string surname;
string forename;
string var;
// ...
bool operator<(const MyData& other) const {
if (surname != other.surname) return surname < other.surname;
if (forename != other.forename) return forename < other.forename;
if (var != other.var) return var < other.var;
// ...
return false; //< They are equal
}
};
Je nach Geschmack kann man sogar einen Makro wie #define COMPARE(field) if (field != other.field) return field < other.field;
will Doppelarbeit zu reduzieren. Dann würde die Funktion wird nur eine Liste von COMPARE
-Anrufungen.
Sie können die Daten in einem boost::tuple
speichern, die lexikographische Vergleich bietet und bieten Zugriffsfunktionen genannt, entlang der Linien von:
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
struct Data {
string &surname() {return stuff.get<0>();}
string &forename() {return stuff.get<1>();}
// it would be polite to add const overloads too.
bool operator<(const Data &other) const {return stuff < other.stuff;}
private:
boost::tuple<string, string> stuff;
};
Ich glaube, das als std::tr1::tuple
auch verfügbar ist, und wird std::tuple
in dem kommenden Standard sein.
Die Aufrechterhaltung der Liste der Zugriffs ist wahrscheinlich besser handhabbar als die Vergleichscode beibehalten wird.
Wenn alle Mitglieder haben die gleiche Art können Sie sie in std::vector
setzen könnte. Standardmäßig wird std::lexicographical_compare
verwendet werden, um Vektoren zu vergleichen.
Sie können mit einem boost::tuple
oder std::pair
die lexigraphical Vergleich eingebaut hat. Natürlich ist der Nachteil nicht, ein Verfahren zu den Tupeln zuordnen können.