Middle
Was muss getan werden, um seine Struktur in einer unordered_map zu speichern?
sobes.tech KI
Antwort von AI
Um eine Struktur als Schlüssel in std::unordered_map zu speichern, ist es notwendig,:
- Hash-Funktion: Findet den Hash-Wert für eine Instanz der Struktur.
- Gleichheitsoperator (
operator==): Vergleicht zwei Instanzen der Struktur auf Gleichheit.
Es gibt mehrere Möglichkeiten, diese Elemente bereitzustellen:
-
Überschreiben von
operator==innerhalb der Struktur und Spezialisierung vonstd::hashfür deine Struktur. Dies ist der gebräuchlichste und empfohlene Ansatz.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; bool operator==(const MyStruct& other) const { return id == other.id && name == other.name; } }; // Spezialisierung von std::hash für MyStruct namespace std { template <> struct hash<MyStruct> { size_t operator()(const MyStruct& obj) const { size_t h1 = hash<int>()(obj.id); size_t h2 = hash<std::string>()(obj.name); return h1 ^ (h2 << 1); } }; } // Beispiel in main int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // äquivalent zu key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] gibt 10 zurück } return 0; } -
Bereitstellen von Hash- und Vergleichsfunktionen als separate Parameter in der Vorlage bei der Deklaration von
unordered_map. Weniger bequem, wenn du die Struktur häufig als Schlüssel verwendest, da du die Typen des Vergleichers und des Hashers bei jeder Deklaration des Containers angeben musst.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Separate Hash-Funktion struct MyStructHash { size_t operator()(const MyStruct& obj) const { size_t h1 = std::hash<int>()(obj.id); size_t h2 = std::hash<std::string>()(obj.name); return h1 ^ (h2 << 1); } }; // Separate Vergleichsfunktion struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Beispiel in main int main() { std::unordered_map<MyStruct, int, MyStructHash, MyStructEqual> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; my_map[key1] = 10; my_map[key2] = 20; return 0; }
Wichtige Punkte:
- Korrektheit der Hash-Funktion: Für beliebige zwei Schlüssel
aundb, wenna == b, dann musshash(a)gleichhash(b)sein. Das Gegenteil ist nicht erforderlich (Kollisionen sind möglich). - Qualität der Hash-Funktion: Eine gute Hash-Funktion verteilt die Hash-Werte gleichmäßig für verschiedene Schlüssel, minimiert Kollisionen und erhöht die Leistung (
O(1)im Durchschnitt). - Konstanz: Die Operatoren für Vergleich und Hash-Funktion sollten
constsein, da sie das Objekt des Schlüssels nicht verändern dürfen.