Middle
Co je třeba udělat, aby se vaše struktura uchovávala v unordered_map?
sobes.tech AI
Odpověď od AI
Chcete-li uložit strukturu jako klíč v std::unordered_map, musíte poskytnout:
- Hashovací funkci (hash function): Najde hash hodnotu pro instanci struktury.
- Operátor rovnosti (
operator==): Porovná dvě instance struktury na rovnost.
Existuje několik způsobů, jak tyto prvky poskytnout:
-
Přepsat
operator==uvnitř struktury a specializovatstd::hashpro vaši strukturu. To je nejběžnější a doporučený pří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; } }; // Specializace std::hash pro 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); } }; } // Příklad použití 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; } -
Poskytnout funkce hashování a porovnání jako samostatné parametry šablony při deklaraci
unordered_map. Méně pohodlné, pokud často používáte strukturu jako klíč, protože musíte uvádět typy porovnávače a hashovače při každé deklaraci kontejneru.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Samostatná funkce hashování 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á funkce porovnání (nebo funktor) struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Příklad použití 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:
- Správnost hashovací funkce: Pro jakékoli dva klíče
aab, pokuda == b, pakhash(a)musí být rovnohash(b). Opak není nutný (mohou nastat kolize). - Kvalita hashovací funkce: Dobrá hashovací funkce rovnoměrně rozděluje hash hodnoty pro různé klíče, minimalizuje kolize a zvyšuje výkon (
O(1)průměrně). - Konzistence: Operátory porovnání a hashovací funkce by měly být
const, protože nemají měnit objekt klíče.