Middle
Какво трябва да направите, за да съхраните структурата си в unordered_map?
sobes.tech AI
Отговор от AI
За да съхранявате структура като ключ в std::unordered_map, трябва да предоставите:
- Функция за хеширане (hash function): Намерете хеш стойността за инстанция на структурата.
- Оператор за сравнение за равенство (
operator==): Сравнява две инстанции на структурата за равенство.
Има няколко начина да предоставите тези елементи:
-
Пренапишете
operator==вътре в структурата и специализирайтеstd::hashза вашата структура. Това е най-често срещаният и препоръчителен подход.#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; } }; // Специализация на std::hash за 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); } }; } // Пример за използване в main int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // еквивалентен на key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] ще даде 10 } return 0; } -
Да предоставите функциите за хеширане и сравнение като отделни параметри на шаблона при обявяване на
unordered_map. По-малко удобно, ако често използвате структурата като ключ, тъй като трябва да посочвате типовете на компаратора и хешера при всяко обявяване на контейнера.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Отделна функция за хеширане 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); } }; // Отделна функция за сравнение (или функтор) struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Пример за използване в 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; }
Важни моменти:
- Коректност на hash функцията: За всеки два ключа
aиb, акоa == b, тогаваhash(a)трябва да е равно наhash(b). Обратното не е задължително (колизии могат да се случат). - Качество на hash функцията: Добра hash функция равномерно разпределя стойностите за различни ключове, минимизирайки колизиите и подобрявайки производителността (
O(1)средно). - Константност: Операторите за сравнение и hash функцията трябва да бъдат
const, тъй като не трябва да променят обекта на ключа.