Middle
Čo je potrebné urobiť, aby ste svoju štruktúru uložili do unordered_map?
sobes.tech AI
Odpoveď od AI
Ak chcete uložiť štruktúru ako kľúč v std::unordered_map, musíte poskytnúť:
- Hashovaciu funkciu (hash function): Nájde hash hodnotu pre inštanciu štruktúry.
- Operátor porovnania na rovnosť (
operator==): Porovnáva dve inštancie štruktúry na rovnosť.
Existuje niekoľko spôsobov, ako tieto prvky poskytnúť:
-
Prepísať
operator==v rámci štruktúry a špecializovaťstd::hashpre vašu štruktúru. Toto je najbežnejší a odporúčaný prístup.#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; } }; // Špecializácia std::hash pre 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); } }; } // Príklad použitia v main int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // ekvivalentný s key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] bude 10 } return 0; } -
Poskytnúť funkcie hashovania a porovnania ako samostatné parametre šablóny pri deklarácii
unordered_map. Menej pohodlné, ak často používate štruktúru ako kľúč, pretože musíte uvádzať typy komparátora a hashovača pri každom vyhlásení kontajnera.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Samostatná funkcia hashovania 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); } }; // Samostatná funkcia porovnania (alebo funktor) struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Príklad použitia v 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; }
Dôležité body:
- Korektnosť hash funkcie: Pre akékoľvek dva kľúče
aab, aka == b, takhash(a)musí byť rovnéhash(b). Opak nie je povinný (môžu nastať kolízie). - Kvalita hash funkcie: Dobrá hash funkcia rovnomerne rozdeľuje hodnoty pre rôzne kľúče, minimalizuje kolízie a zvyšuje výkon (
O(1)v priemere). - Konštantnosť: Operátory porovnania a hash funkcia by mali byť
const, pretože nemajú meniť objekt kľúča.