Was ist der einfachste Weg, lexikographischen Vergleich für Elemente einer Klasse definieren?

StackOverflow https://stackoverflow.com/questions/2500664

  •  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.

War es hilfreich?

Lösung 2

Mit dem Aufkommen von C ++ 11 gibt es eine neue und übersichtliche Art und Weise dies mit

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top