Wie kann ich eine ungeordnete Menge von Paaren von ganzen zahlen in C++?
Im folgenden Programm wird nicht kompiliert, eine ungeordnete Menge von Paaren von ganzen zahlen, aber es funktioniert für ganze zahlen. Kann unordered_set
und Ihre member-Funktionen verwendet werden, die auf Benutzer-definierte Typen, und wie kann ich es definieren?
#include <unordered_set>
...
class A{
...
private:
std::unordered_set< std::pair<int, int> > u_edge_;
};
Compiler-Fehler:
Fehler: keine passende Funktion für Aufruf von " std::unordered_set >::unordered_set()'
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihren code kompiliert auf VS2010 SP1 (VC10), aber es versäumt, zu kompilieren mit GCC-g++ 4.7.2.
Allerdings möchten Sie vielleicht zu prüfen
boost::hash
aus Boost.Funktionale hash einstd::pair
(mit diesem Zusatz-code, kompiliert auch mit g++).Es gibt keine standard-Weg, der die Berechnung eines hash auf ein paar. Fügen Sie diese definition mit Ihrer Datei:
Nun können Sie es wie folgt:
Dies funktioniert, weil
pair<T1,T2>
definiert Gleichheit. Für benutzerdefinierte Klassen, die nicht bieten eine Methode zum testen der Gleichheit, die Sie möglicherweise benötigen, um eine separate Funktion, um zu testen, ob zwei Instanzen gleich sind, um einander.Natürlich ist diese Lösung beschränkt sich auf ein paar von zwei zahlen. Hier ist ein link zu einer Antwort, die Ihnen hilft, zu definieren, eine mehr Allgemeine Weise des Verdienens des hash für mehrere Objekte.
Das problem ist, dass
std::unordered_set
ist mitstd::hash
Vorlage zu berechnen hashes für seine Einträge und es gibt keinestd::hash
Spezialisierung für Paare. So haben Sie zwei Dinge tun:std::hash
für Ihre Schlüssel-Typ (std::pair<int, int>
) Verwendung dieser Funktion.Hier ist ein einfaches Beispiel:
Müssen Sie eine Spezialisierung für
std::hash<>
funktioniert mitstd::pair<int, int>
. Hier ist ein sehr einfaches Beispiel von, wie könnte man definieren, ist die Spezialisierung:Ihnen fehlt eine hash-Funktion für
std::pair<int, int>>
. Zum Beispiel,Können Sie sich auch spezialisieren
std::hash<T>
fürstd::hash<std::pair<int,int>>
, in dem Fall kann man weglassen, der zweite template-parameter.std::unordered_set
ich denke, es ist sicher davon ausgehen, dass OP will einen C++11-Lösung.Den anderen Antworten hier alle vorschlagen, Aufbau einer hash-Funktion, die irgendwie verbindet Sie Ihre zwei Ganzzahlen.
Dies funktionieren wird, aber produziert nicht-unique-hashes. Obwohl dies ist gut für Ihre Nutzung des
unordered_set
für einige Anwendungen ist es möglicherweise nicht akzeptabel ist. In Ihrem Fall, wenn Sie geschehen, wählen Sie eine schlechte hash-Funktion, kann es dazu führen, dass viele unnötige Kollisionen.Aber können Sie produzieren, eindeutige hashes!
int
ist in der Regel 4 bytes. Könnten Sie dies explizit durch die Verwendungint32_t
.Den hash-Datentyp ist
std::size_t
. Auf den meisten Maschinen, das ist 8 Byte. Sie können überprüfen, diese bei der Zusammenstellung.Seit ein paar besteht aus zwei
int32_t
- Typen, können Sie beide zahlen in einstd::size_t
um einen eindeutigen hash.Die wie folgt aussieht (ich kann nicht erinnern, kurzentschlossen, wie um den compiler zu zwingen behandeln ein Wert mit Vorzeichen, als wäre es für unsigned bit-manipulation, so habe ich das folgende geschrieben für
uint32_t
.):Wie bereits erwähnt, in den meisten anderen Antworten auf diese Frage, müssen Sie, um eine hash-Funktion für
std::pair<int, int>
. Da jedoch C++11, Sie können auch eine lambda-Ausdruck statt der Definition einer hash-Funktion. Der folgende code nimmt die Lösung gegeben durch dasblinkenlight als Grundlage:Code auf Ideone
Möchte ich wiederholen dasblinkenlight s Haftungsausschluss: Diese Lösung beschränkt sich auf ein paar von zwei zahlen. Diese Antwort liefert die Idee für eine Allgemeine Lösung.