Middle
Ce trebuie să faci pentru a-ți stoca structura în unordered_map?
sobes.tech AI
Răspuns de la AI
Pentru a stoca o structură ca și cheie în std::unordered_map, trebuie să furnizați:
- Funcția de hash (hash function): Găsește valoarea hash pentru o instanță a structurii.
- Operatorul de comparare pentru egalitate (
operator==): Compară două instanțe ale structurii pentru egalitate.
Există mai multe moduri de a furniza aceste elemente:
-
Supraincarcă
operator==în interiorul structurii și specializeazăstd::hashpentru structura ta. Aceasta este abordarea cea mai comună și recomandată.#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; } }; // Specializare a std::hash pentru 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); } }; } // Exemplu de utilizare în main int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // echivalent cu key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] va returna 10 } return 0; } -
Furnizați funcții de hash și comparare ca parametri separați în șablonul de declarație al
unordered_map. Mai puțin convenabil dacă folosiți frecvent structura ca și cheie, deoarece trebuie să specificați tipurile comparatorului și hash-ului la fiecare declarație a containerului.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Funcție de hash separată 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); } }; // Funcție de comparare separată struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Exemplu de utilizare în 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; }
Puncte importante:
- Corectitudinea funcției de hash: Pentru orice două chei
așib, dacăa == b, atuncihash(a)trebuie să fie egal cuhash(b). Inversul nu este necesar (coliziile pot apărea). - Calitatea funcției de hash: O funcție de hash bună distribuie uniform valorile hash pentru diferite chei, minimizând coliziunile și îmbunătățind performanța (
O(1)în medie). - Constanța: Operatorii de comparare și funcția de hash trebuie să fie
const, deoarece nu trebuie să modifice obiectul cheie.