Sobes.tech
Middle

Ko nepieciešams darīt, lai saglabātu savu struktūru unordered_map?

sobes.tech AI

Atbilde no AI

Lai izmantotu struktūru kā atslēgu std::unordered_map, ir jānodrošina:

  1. Hesh funkcija (hash function): Tā atrod struktūras piemēra hēša vērtību.
  2. Salīdzināšanas operators (operator==): Tas salīdzina divus struktūras piemērus ar vienādību.

Ir vairāki veidi, kā nodrošināt šos elementus:

  • Pārdefinēt operator== struktūrā un specializēt std::hash jūsu struktūrai. Tas ir visbiežāk izmantotais un ieteicamais veids.

    #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` specializācija 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);
            }
        };
    }
    
    // Piemērs izmantošanai main()
    int main() {
        std::unordered_map<MyStruct, int> my_map;
        MyStruct key1 = {1, "Alice"};
        MyStruct key2 = {2, "Bob"};
        MyStruct key3 = {1, "Alice"}; // līdzīgs ar key1
    
        my_map[key1] = 10;
        my_map[key2] = 20;
    
        if (my_map.count(key3)) {
            // my_map[key3] dos 10
        }
    
        return 0;
    }
    
  • Nodrošināt hesh funkciju un salīdzināšanas funkciju kā atsevišķus parametrus unordered_map deklarācijā. Tas ir mazāk ērti, ja bieži izmantojat struktūru kā atslēgu, jo katru reizi ir jānorāda salīdzināšanas un hesh funkcijas.

    #include <unordered_map>
    #include <string>
    #include <functional>
    
    struct MyStruct {
        int id;
        std::string name;
    };
    
    // Atsevišķa 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);
        }
    };
    
    // Atsevišķa salīdzināšanas funkcija (vai funktors)
    struct MyStructEqual {
        bool operator()(const MyStruct& lhs, const MyStruct& rhs) const {
            return lhs.id == rhs.id && lhs.name == rhs.name;
        }
    };
    
    // Piemērs izmantošanai 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;
    }
    

Svarīgi punkti:

  • Hesh funkcijas korektums: Lai jebkurām divām atslēgām a un b, ja a == b, tad hash(a) ir vienāds ar hash(b). Atgrieztā vērtība var atšķirties, ja a != b (kolīzijas).`
  • Hesh funkcijas kvalitāte: Labas hesh funkcija vienmērīgi sadala hesh vērtības dažādām atslēgām, samazinot kolīzijas un uzlabojot veiktspēju (O(1) vidēji).
  • Konstantums: Operatoriem salīdzināšanai un hesh funkcijai jābūt const, jo tie nedrīkst mainīt atslēgas objektu.