Sobes.tech
Middle

Yapınızı unordered_map'te saklamak için ne yapmanız gerekiyor?

sobes.tech yapay zeka

AI'dan gelen yanıt

std::unordered_map içinde anahtar olarak bir yapı saklamak için şu öğeleri sağlamanız gerekir:

  1. Hash fonksiyonu: Yapı örneği için hash değerini bulur.
  2. Eşitlik karşılaştırma operatörü (operator==): İki yapı örneğini karşılaştırır ve eşit olup olmadıklarını belirler.

Bunları sağlamak için birkaç yöntem vardır:

  • Yapı içinde operator=='yi aşırı yükleyin ve yapınız için std::hash'ı uzmanlaştırın. Bu en yaygın ve önerilen yaklaşımdır.

    #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 için std::hash uzmanlaştırması
    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 içinde kullanım örneği
    int main() {
        std::unordered_map<MyStruct, int> my_map;
        MyStruct key1 = {1, "Alice"};
        MyStruct key2 = {2, "Bob"};
        MyStruct key3 = {1, "Alice"}; // eşdeğer anahtar
    
        my_map[key1] = 10;
        my_map[key2] = 20;
    
        if (my_map.count(key3)) {
            // my_map[key3] 10 döner
        }
    
        return 0;
    }
    
  • Hash fonksiyonları ve karşılaştırma fonksiyonlarını unordered_map'ın şablon parametreleri olarak sağlayın. Bu, yapıyı sık kullandığınızda daha az uygundur çünkü her seferinde karşılaştırıcı ve hash türlerini belirtmeniz gerekir.

    #include <unordered_map>
    #include <string>
    #include <functional>
    
    struct MyStruct {
        int id;
        std::string name;
    };
    
    // Ayrık hash fonksiyonu
    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);
        }
    };
    
    // Ayrık karşılaştırma fonksiyonu
    struct MyStructEqual {
        bool operator()(const MyStruct& lhs, const MyStruct& rhs) const {
            return lhs.id == rhs.id && lhs.name == rhs.name;
        }
    };
    
    // main içinde kullanım örneği
    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;
    }
    

Önemli noktalar:

  • Hash fonksiyonunun doğruluğu: Herhangi iki anahtar a ve b için, eğer a == b ise, hash(a) ile hash(b) eşit olmalıdır. Tersine gerek yoktur (kollizyonlar olabilir).
  • Hash fonksiyonunun kalitesi: İyi bir hash fonksiyonu, farklı anahtarlar için hash değerlerini düzgün dağıtır, çakışmaları en aza indirir ve performansı artırır (O(1) ortalama).
  • Sabitlik: Karşılaştırma operatörleri ve hash fonksiyonu const olmalıdır, çünkü anahtar nesnesini değiştirmemelidirler.