Middle
Ką reikia padaryti, kad išsaugotumėte savo struktūrą unordered_map?
sobes.tech AI
Atsakymas iš AI
Norint naudoti struktūrą kaip rakto std::unordered_map, būtina pateikti:
- Hesh funkciją (hash function): Ji suras struktūros pavyzdžio hesh reikšmę.
- Lyginimo operatorių (
operator==): Jis palygins du struktūros pavyzdžius lygybei.
Yra keli būdai pateikti šiuos elementus:
-
Perrašyti
operator==struktūroje ir specializuotistd::hashjūsų struktūrai. Tai yra dažniausiai naudojamas ir rekomenduojamas būdas.#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` specializacija 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); } }; } // Pavyzdys naudojant main() int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // lygi su key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] duos 10 } return 0; } -
Pateikti hesh funkciją ir lyginimo funkciją kaip atskirus parametrus
unordered_mapdeklaracijoje. Tai mažiau patogu, jei dažnai naudojate struktūrą kaip raktą, nes kiekvieną kartą reikia nurodyti lyginimo ir hesh funkcijas.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Atskira hesh funkcija 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); } }; // Atskira lyginimo funkcija (arba funktoras) struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Pavyzdys naudojant 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; }
Svarbūs punktai:
- Hesh funkcijos teisingumas: Bet kuriems dviem raktams
airb, jeia == b, tadahash(a)turi būti lygushash(b). Atvirkščiai nereikalaujama (galimi kolizijos).` - Hesh funkcijos kokybė: Geras hesh funkcija tolygiai paskirsto hesh reikšmes įvairiems raktams, sumažindama kolizijas ir gerindama našumą (
O(1)vidutiniškai). - Konstantumas: Lyginimo ir hesh operatoriai turi būti
const, nes jie neturi keisti rakto objekto.