Middle
Wat moet je doen om je structuur op te slaan in een unordered_map?
sobes.tech AI
Antwoord van AI
Om een structuur als sleutel op te slaan in std::unordered_map, moet je het volgende voorzien:
- Hashfunctie: Bepaalt de hash-waarde voor een instantie van de structuur.
- Gelijkheidsoperator (
operator==): Vergelijkt twee instanties van de structuur op gelijkheid.
Er zijn verschillende manieren om deze elementen te voorzien:
-
Overschrijf
operator==binnen de structuur en specialiseertstd::hashvoor jouw structuur. Dit is de meest gebruikelijke en aanbevolen aanpak.#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; } }; // Specialisatie van std::hash voor 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); } }; } // Voorbeeld gebruik in main int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // gelijkwaardig aan key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] geeft 10 } return 0; } -
Voorzie hash- en vergelijkingsfuncties als aparte parameters in de template bij het declareren van
unordered_map. Minder handig als je de structuur vaak als sleutel gebruikt, omdat je de types van comparator en hasher bij elke declaratie moet specificeren.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Aparte hashfunctie 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); } }; // Aparte vergelijkingsfunctie struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Voorbeeld gebruik 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; }
Belangrijke punten:
- Correctheid van de hashfunctie: Voor elke twee sleutels
aenb, alsa == b, dan moethash(a)gelijk zijn aanhash(b). Het omgekeerde is niet vereist (collisionen kunnen voorkomen). - Kwaliteit van de hashfunctie: Een goede hashfunctie verdeelt de hash-waarden gelijkmatig over verschillende sleutels, minimaliseert collisionen en verbetert de prestaties (
O(1)gemiddeld). - Constantie: De operators voor vergelijking en hashfunctie moeten
constzijn, omdat ze het sleutelobject niet mogen wijzigen.