2017-04-12 2 views
0

Ich habe einen Vektor von Paaren von ints, heißtIst es möglich, Operatoren in einer vorhandenen Klasse zu ändern oder "anzupassen"?

std::vector< std::pair<int, int> > V; 

Ich wollte diesen Vektor sortieren, so schrieb ich eine quicksort Umsetzung. Glücklicherweise definiert std::pair bereits intelligente Vergleichsoperatoren, so dass

[[3, 1], [1, 7], [3, 5]] 

Sortierungen

[[1, 7], [3, 1], [3, 5]] 

d.h. durch das erste Element jedes Paares das Sortieren, das zweite Element als Tie-Break verwenden.

Aber was ich eigentlich will, ist das zweite Element in abnehmenden Reihenfolge zu vergleichen. So sollte das obige Beispiel als

sortiert werden
[[1, 7], [3, 5], [3, 1]] 

Ist es möglich, die Vergleichsoperatoren von std::pair so außer Kraft zu setzen, dass ich durch die Erhöhung der ersten und zweiten Abnahme-Element sortieren? Wenn nicht, was ist der beste Weg dies zu erreichen, Design-weise?

Ich dachte über ein Kind Klasse von std::pair abzuleiten, die alle Vergleichsoperatoren overrode, aber dies erforderlich reinterpret_caststd::pair<int, int>* auf Zeiger auf mein Kind Klasse ing, die sehr falsch anfühlt.

Ist eine separate, statische Hilfsklasse der einzige Weg dann? (Abgesehen von Hacks wie Multiplikation aller zweiten Elemente mit -1, vorausgesetzt, dass alle Werte positiv sind.)

Antwort

1

Sie sollten dem allgemeinen Entwurfsprinzip der C++ - Bibliothek folgen und Komparatoren verwenden. Geordnete assoziative Containervorlagen wie std::set verfügen über einen optionalen Vorlagenparameter, eine Vergleichsklasse, die die Sortierreihenfolge festlegt. Zum Beispiel:

std::set<int> 

Gibt Ihnen einen Satz, der seine int Werte in der Natur, zu erhöhen, um bestellt. Das Iterieren über diesen Bestand wird über seine Werte von den kleinsten bis zu den höchsten Werten iterieren.

Aber das ist nur, weil std::set hat wirklich eine zweite Vorlage Parameter, der Komparator, der standardmäßig auf std::less, die im Grunde ist ein Wrapper für die < Operator. Diese std::set ist wirklich:

std::set<int, std::less<int>> 

(Es gibt auch einen dritten Template-Parameter, die für die Zwecke dieser Diskussion nicht relevant ist).

Wenn Sie wollen Sie könnten erklären, stattdessen ein:

std::set<int, std::greater<int>> 

Und dann, wenn Sie über diesen Satz wiederholen, würden Sie feststellen, dass Sie von den größten bis zum kleinsten Iterieren würden Werte im Satz. In jeder anderen Hinsicht funktioniert dieses Set wie ein gewöhnliches Set.

In ähnlicher Weise sprechen wir über diese Quicksort-Implementierung, die Sie geschrieben haben.Ihr Quicksort verwendet den Operator < direkt, um Ihre std::pair s zu vergleichen. Sie sollten Ihre Quicksort-Implementierung einfach neu schreiben, um einen zusätzlichen Parameter, einen Komparator, zu verwenden, der die Sortierreihenfolge angibt. Anstatt nur den überladenen <-Operator zu verwenden, ruft Ihre Quicksort-Implementierung stattdessen den Komparator auf, um die beiden Paare zu vergleichen.

Jetzt können Sie Ihre Paare in einer beliebigen Reihenfolge mit einem einzigen aufrufbaren Objekt, das zwei beliebige s enthält, in eine Reihenfolge bringen und deren relative Reihenfolge berechnen.

+0

Ich sehe, also Sie sagen, dass der benutzerdefinierte Vergleich außerhalb jeder Beziehung zu 'std :: pair' existieren sollte, stattdessen implementiert als Teil der Quicksort-Implementierung. Klingt sauber, ich werde es so machen. Dennoch bin ich neugierig auf etwas, mehr aus einer theoretischen Perspektive: –

+0

Wenn, sagen wir, eine Menge Algorithmen in '' oder einer anderen Bibliothek, manipulieren und sortieren meinen Vektor von 'std :: pair's einfach in Ordnung. Aber sagen Sie, jetzt möchte ich, dass alle von ihnen eine andere Reihenfolge betrachten (z. B. absteigendes zweites Element). Dann scheint es nicht verschwenderisch, jeden Algorithmus zu bitten, einen Vergleichsparameter zu nehmen? Haben Sie irgendwelche Einsichten darüber, warum die "Anordnung" eines Typs nicht dem Typ eigen sein sollte, im Gegensatz zu einer Verantwortung der Dinge, die diesen Typ manipulieren? –

Verwandte Themen