Middle
Mit kell tenni ahhoz, hogy a szerkezetedet unordered_map-ben tárold?
sobes.tech MI
Válasz az MI-től
Ahhoz, hogy egy struktúrát kulcsként tároljunk az std::unordered_map-ban, meg kell adni:
- Hash függvény: Megkeresi a hash értéket a struktúra példányára.
- Egyenlőség operátor (
operator==): Összehasonlít két struktúra példányt egyenlőség szempontjából.
Ezeket az elemeket többféleképpen lehet biztosítani:
-
Felülírni az
operator==-t a struktúrában és specializálni azstd::hash-t a struktúrádhoz. Ez a leggyakoribb és ajánlott megközelítés.#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; } }; // Az `std::hash` specializálása a MyStruct-hez 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); } }; } // Használati példa a main-ben int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // ekvivalens a key1-gyel my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] 10 lesz } return 0; } -
Biztosítani a hash és összehasonlító függvényeket külön paraméterként az
unordered_mapdeklarációjánál. Ez kevésbé kényelmes, ha gyakran használod a struktúrát kulcsként, mert minden alkalommal meg kell adni a típusokat.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Külön hash függvény 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); } }; // Külön összehasonlító függvény (vagy funktor) struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Használati példa a main-ben 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; }
Fontos megjegyzések:
- A hash függvény helyessége: Bármely két kulcs
aésbesetén, haa == b, akkorhash(a)éshash(b)ugyanaz legyen. A fordítva nem kötelező (kollíziók lehetségesek). - A hash függvény minősége: Egy jó hash függvény egyenletesen osztja el a hash értékeket különböző kulcsok között, minimalizálva a kollíziókat és javítva a teljesítményt (
O(1)átlagosan). - Állandóság: A összehasonlító operátorok és a hash függvény
consttípusúak kell legyenek, mivel nem szabad módosítaniuk a kulcs objektumát.