Frage

Wie operator< auf n-Tupel (zum Beispiel auf 3-fach) zu definieren, so dass es strenge schwache Ordnung erfüllen Konzept? Ich weiß, dass Boost-Bibliothek Tupel Klasse mit korrekt definiert operator< aber aus irgendwelchen Gründen kann ich es nicht verwenden.

War es hilfreich?

Lösung

if (a1 < b1)
  return true;
if (b1 < a1)
  return false;

// a1==b1: continue with element 2
if (a2 < b2)
  return true;
if (b2 < a2)
  return false;

// a2 == b2: continue with element 3
if (a3 < b3)
  return true;
return false; // early out

Dies ordnet die Elemente von a1 am meisten siginificant und a3 niedrigstwertigen.

Dies kann ad infinitum fortgesetzt werden, können Sie auch zum Beispiel es auf einen Vektor von T, Iterieren über Vergleiche von a [i]

while (i<count-1 && !(a[i] < a[i+1]) && !(a[i+1] < a[i])
  ++i;
return i < count-1 && a[i] < a[i+1];

Natürlich, wenn der Vergleich teuer ist, können Sie das Vergleichsergebnis zwischenzuspeichern.


[Bearbeiten] entfernt falscher Code


[Bearbeiten], wenn mehr als nur operator< verfügbar ist, neige ich dazu, um das Muster zu verwenden

if (a1 != b1)
  return a1 < b1;

if (a2 != b2)
  return a2 < b2;

...

Andere Tipps

... eine neue Antwort auf eine sehr alte Frage, aber die bestehende Antwort vermisst die einfache Lösung von C ++ 11 ...

C ++ 11-Lösung

C ++ 11 ff bietet std::tuple<T...> , mit dem Sie Ihre Daten speichern können. tuples haben einen passenden operator< , die zunächst das am weitesten links stehende Element vergleicht, arbeitet dann entlang des Tupels bis das Ergebnis ist klar. Das ist geeignet für die Bereitstellung der strenge schwache Ordnung erwartet zum Beispiel durch std::set und std::map .

Wenn Sie Daten in einigen anderen Variablen (zB Felder in einem struct) haben, können Sie auch benutzen std::tie() ein Tupel erzeugt Referenzen , die dann zu einer anderen solchen Tupel verglichen werden können. Das macht es leicht operator< für bestimmte Mitgliedsdatenfelder in einer benutzerdefinierten class / struct Art zu schreiben:

struct My_Struct
{
    int a_;
    double b_;
    std::string c_;
};

bool operator<(const My_Struct& lhs, const My_Struct& rhs)
{
    return std::tie(lhs.a_, lhs.b_, lhs.c_) < std::tie(rhs.a_, rhs.b_, rhs.c_);
}

Sie können einfach verwenden Drei-Element-Vektoren, die bereits Betreiber haben <() passend definiert. Dies hat den Vorteil, dass es zu N-Elemente erweitert, ohne dass Sie etwas zu tun.

Die Grundströmung sollte entlang der Linien sein: , wenn die K-ten Elemente unterschiedlich sind, kehren die zum nächsten Element gehen kleiner sonst . Der Code folgenden vorausgesetzt, dass Sie nicht haben sonst eine Boost-Tupel Sie get<N>(tuple) und nicht haben, das Problem zu beginnen verwenden würde.

if (lhs.first != rhs.first)
    return lhs.first < rhs.first;                
if (lhs.second != rhs.second)
    return lhs.second< rhs.second;
return lhs.third < rhs.third;

Auch wenn Sie nicht die Boost-Version verwenden, sollten Sie den Code zu nick können. Ich eingekerbt dies von std :: pair - ein 3-Tupel ähnlich sein wird, ich denke,

.
return (_Left.first < _Right.first ||
        !(_Right.first < _Left.first) && _Left.second < _Right.second);

Edit:. Als ein paar Leute aus haben darauf, wenn Sie Code aus der Standardbibliothek stehlen in Ihrem Code zu verwenden, sollten Sie die Dinge benennen, die Unterstreichungen auf der Vorderseite haben, wie diese Namen reserviert sind

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