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; } }; // `MyStruct` үчүн `std::hash` атайын кылуу 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; }
Мөөнөттүү маанилүү:
- Хеш-функциянын тууралыгы: Ар бир эки ачкыч
aжанаbүчүн, эгерa == b, андаhash(a)жанаhash(b)бирдей болушу керек. Артка кайтуу керек эмес (коллизиялар болушу мүмкүн). - Хеш-функциянын сапаты: Жакшы хеш-функция ар түрдүү ачкычтар үчүн хеш маанилерди бирдей бөлүштүрөт, коллизияларды минималдаштырат жана иштөө ылдамдыгын жакшыртат (
O(1)орто эсеп менен). - Константтык: Теңдештирүү операторлору жана хеш-функция
constболушу керек, анткени алар ачкыч объектисин өзгөртпөшү керек эмес.