unordered_map,为什么有些桶有多个元素甚至散列值都不同?

时间:2015-08-17 00:14:09

标签: c++ c++11 hash unordered-map

我正在使用std::unordered_map的默认哈希函数并检查是否发生了冲突。以下是代码:

void check(std::map<long, bool> & mp, const string & s, const long v){
    if(mp.count(v) == 0){
        mp[v] = true;
    }else{
        cout<<"collision for "<<s<<endl;
    }
}
int main(){
    std::unordered_map<std::string, long> um;
    std::map<long, bool> map;
    auto hasher = um.hash_function();

    std::string str = "";

long count = 0;

    for (int i = 0; i < 26; ++i)
    {
        str = char(65+i);
        um[str];
        auto value = hasher(str);
        check(map, str, value);

        for (int j = 0; j < 26; ++j)
        {
            str = char(65+i);
            str += char(65+j);
            um[str];
            auto value = hasher(str);
            check(map, str, value);

            for (int k = 0; k < 26; ++k)
            {
                str = char(65+i);
                str += char(65+j);
                str += char(65+k);
                um[str];
                auto value = hasher(str);
                check(map, str, value);

                for (int l = 0; l < 26; ++l)
                {
                    str = char(65+i);
                    str += char(65+j);
                    str += char(65+k);
                    str += char(65+l);
                    um[str];
                    auto value = hasher(str);
                    check(map, str, value);

                    for (int m = 0; m < 26; ++m)
                    {
                        str = char(65+i);
                        str += char(65+j);
                        str += char(65+k);
                        str += char(65+l);
                        str += char(65+m);
                        um[str];
                        auto value = hasher(str);
                        check(map, str, value);
                    }
                }
            }
        }
    }
        for(int i = 0; i < um.bucket_count(); ++i){
        if(um.bucket_size(i) >= 2)cout<<"um_collison happened at "<<i<<"  "<<um.bucket_size(i)<<endl;
    }

    return 0;
}

我遇到的问题是,我发现collision for没有输出,但有很多输出,例如um_collison happened at 17961055 3,我正在使用g++ 4.9.2,为什么字符串被哈希不同的值,但一些桶仍然有超过1个元素?

1 个答案:

答案 0 :(得分:3)

hasher函数返回的值是size_t。当给定随机输入时,假设hasher函数至少给出弱伪随机(即“成对独立”或类似的)输出。但是,hasher函数的输出不直接用作给定输入的bin号。这将要求std :: unordered_map在64位计算机上有2 ^ 64个二进制文件...这是太多的内存。

相反,根据当前的元素数量,有一定数量的区间,比如说B.地图将采用哈希的输出,模数B,通常,将项目映射到区间。因此具有不同散列的物品可以到达相同的箱子。一旦哈希表变得太紧密,取决于一些启发式方法,通常会增加B并且项目将被重新设置以减少冲突的数量。也就是说,我们重新计算所有哈希值,然后将它们模数为B'而不是更大的B'。但它究竟是如何工作的是一个实现细节。