/ / std :: map, benutzerdefinierter Schlüsseltyp mit Sortierung nur für eine Variable - c ++, map, Operatoren, std

std :: map, benutzerdefinierter Schlüsseltyp mit Sortierung nur für eine Variable - c ++, map, operators, std

Ich habe einen Schlüsseltyp:

struct KeyT {
uint32_t timestamp;

// example!
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
uint32_t e;
// ...

bool operator== (const KeyT& key) const
{
if(timestamp == key.timestamp && a == key.a && b == key.b && d == key.d && c == key.c && e == key.e)
return true;
return false;

}
bool operator< (const KeyT& key) const
{
if(timestamp < key.timestamp)
return true;
else if(timestamp == key.timestamp && a < key.a && b < key.b && c < key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b < key.b && c < key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b == key.b && c < key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d < key.d && e < key.e)
return true;
else if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d == key.d && e < key.e)
return true;
// ..
return false;
}
};

Nun kümmert mich das Sortieren nicht wirklichMember Vars A, B, C, D, E, die einzige Sache, die ich sicherstellen möchte, ist, dass die Karte nach Zeitstempel sortiert wird. Ich habe auch gerade begriffen, dass, wenn ich zwei Instanzen von KeyT eins, zwei habe, bei denen alles außer "d" gleich ist, dann beide eins <zwei und zwei <eins falsch sind. Die einzige Möglichkeit, dies zu beheben, besteht darin, Vergleiche für alle möglichen Kombinationen aller Elementvariablen zu schreiben. Ich bin ziemlich sicher, dass mir etwas Offensichtliches fehlt, was ist die beste Lösung in diesem Fall?

Vielen Dank!

Antworten:

6 für die Antwort № 1

Ich denke das macht was du brauchst:

bool operator< (const KeyT& key) const
{
if(timestamp != key.timestamp) return timestamp < key.timestamp;
else if ( a != key.a ) return a < key.a;
else if ( b != key.b ) return b < key.b;
else if ( c != key.c ) return c < key.c;
else if ( d != key.d ) return d < key.d;
else return e < key.e;
}

Dies ist ein sinnvolles, wenn auch hässliches Muster, wenn Sie eine priorisierte Liste von Variablen haben, nach denen Sie innerhalb einer vergleichbaren Klasse sortieren möchten.


1 für die Antwort № 2

Zuerst sollten Sie nur den nächsten aktuellen Schlüssel vergleichen, der nicht verglichen wurde, um weniger als zu sein else nach return, so was:

bool operator< (const KeyT& key) const
{
if(timestamp < key.timestamp)
return true;
if(timestamp == key.timestamp && a < key.a)
return true;
if(timestamp == key.timestamp && a == key.a && b < key.b)
return true;
if(timestamp == key.timestamp && a == key.a && b == key.b && c < key.c)
return true;
if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d < key.d)
return true;
if(timestamp == key.timestamp && a == key.a && b == key.b && c == key.c && d == key.d && e < key.e)
return true;
// ..
return false;
}

Wenn Sie nur den Zeitstempel vergleichen müssen, lassen Sie den ersten ifund lösche die restlichen:

bool operator< (const KeyT& key) const
{
return timestamp < key.timestamp;
}

Wenn Sie diesen Operator zum Vergleichen Ihrer Schlüssel verwenden, werden Elemente mit identischem Zeitstempel nicht neu angeordnet.


0 für die Antwort № 3

Wenn Sie sich nur um den Zeitstempel kümmern, und denBei anderen Attributen spielt es keine Rolle. Sie können Folgendes verwenden, eine strikte, schwache Reihenfolge. Sie werden einfach nie wissen, in welcher Reihenfolge die Objekte mit demselben Zeitstempel erscheinen:

bool operator< (const KeyT& key) const
{
return timestamp < key.timestamp;
}

Wenn Sie alle Attribute bestellen müssen, schlage ich vor boost::tie:

bool operator< (const KeyT& key) const
{
return boost::tie(timestamp, a, b, c, d, e) < boost::tie(key.timestamp, key.a, key.b, key.c, key.d, e.key);
}