Hinweise zur Datenstruktur – verwandte Anwendungen von Hash-Tabellen (RandomPool-Struktur, Bloom-Filter und konsistenter Hash-Algorithmus)

Inhaltsverzeichnis

1 – RandomPool-Struktur

2 – Bloom-Filter

3-- Konsistentes Hashing


1 – RandomPool-Struktur

Das Entwerfen einer RandomPool-Struktur erfordert die folgenden drei Funktionen:

        ① Einfügen (Schlüssel): Fügen Sie der Struktur einen bestimmten Schlüssel hinzu und fügen Sie ihn nicht wiederholt hinzu.

        ② delete(key): Entfernen Sie den Schlüssel in der Struktur;

        ③ getRandom(): Gibt zufällig einen Schlüssel in der Struktur mit gleicher Wahrscheinlichkeit zurück;

Anforderungen: Die zeitliche Komplexität der oben genannten drei Funktionen beträgt O(1);

Hauptideen:

        Verwenden Sie die beiden Hash-Tabellen indexKeymap und keyIndexmap zum Speichern von (Schlüssel, Index) und (Index, Schlüssel), wobei der Index kontinuierlich von 0 ansteigt, was mit der Größe der Hash-Tabelle zusammenhängt.

#include <iostream>
#include <unordered_map>
#include <string>

class randomPool{
public:
    void insertKey(std::string key){
        if(keyIndexmap.find(key) == keyIndexmap.end()){
            keyIndexmap[key] = this->size;
            indexKeymap[this->size] = key;
            this->size++;
        }
    }

    void deleteKey(std::string key){
        if(keyIndexmap.find(key) != keyIndexmap.end()){
            int deleteIndex = keyIndexmap[key];
            int lastIndex = this->size - 1;
            std::string lastKey = indexKeymap[lastIndex];
            // 使用(lastKey, lastIndex)替换删除的(key, deleteIndex)
            keyIndexmap[lastKey] = deleteIndex;
            indexKeymap[deleteIndex] = lastKey;
            // 移除(key, deleteIndex) 和 (lastIndex, lastKey)
            // 此步骤的意义是确保indexKeymap中的index是逻辑连续的,以便getRandomKey()的调用
            keyIndexmap.erase(key);
            indexKeymap.erase(lastIndex);
        }
    }

    std::string getRandomKey(){
        //随机生成[0, size - 1]上的 index
        int random = rand() % size;
        return indexKeymap[random];
    }

public:
    std::unordered_map<std::string, int> keyIndexmap;
    std::unordered_map<int, std::string> indexKeymap;
    int size = 0;
};

int main(int argc, char *argv[]){
    randomPool rp1;
    rp1.insertKey("A");
    rp1.insertKey("B");
    rp1.insertKey("C");
    std::cout << "***************keyIndexmap: " << std::endl;
    for(auto &it : rp1.keyIndexmap){
        std::cout << "(" << it.first << ", " << it.second << ")" << std::endl; 
    }

    std::cout << "***************indexKeymap: " << std::endl;
    for(auto &it : rp1.indexKeymap){
        std::cout << "(" << it.first << ", " << it.second << ")" << std::endl; 
    }

    std::cout << "***************After deleteKey:" << std::endl;
    rp1.deleteKey("A");
    std::cout << "***************keyIndexmap: " << std::endl;
    for(auto &it : rp1.keyIndexmap){
        std::cout << "(" << it.first << ", " << it.second << ")" << std::endl; 
    }

    std::cout << "***************getRandomkey: " << rp1.getRandomKey() << std::endl;
    return 0;
}

2 – Bloom-Filter

Bloom-Filter werden im Allgemeinen zum Abrufen von Informationen verwendet. Videoerklärungen finden Sie unter: Bloom-Filter-Erklärungen (Video beginnt bei 1:08:00)

3-- Konsistentes Hashing

Der konsistente Hash-Algorithmus wird häufig beim Lastausgleich verwendet. Videoerklärungen finden Sie unter: 7-minütiges Video zur Erläuterung des konsistenten Hash-Algorithmus

Supongo que te gusta

Origin blog.csdn.net/weixin_43863869/article/details/132367688
Recomendado
Clasificación