我正在使用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个元素?
答案 0 :(得分:3)
hasher函数返回的值是size_t。当给定随机输入时,假设hasher函数至少给出弱伪随机(即“成对独立”或类似的)输出。但是,hasher函数的输出不直接用作给定输入的bin号。这将要求std :: unordered_map在64位计算机上有2 ^ 64个二进制文件...这是太多的内存。
相反,根据当前的元素数量,有一定数量的区间,比如说B.地图将采用哈希的输出,模数B,通常,将项目映射到区间。因此具有不同散列的物品可以到达相同的箱子。一旦哈希表变得太紧密,取决于一些启发式方法,通常会增加B并且项目将被重新设置以减少冲突的数量。也就是说,我们重新计算所有哈希值,然后将它们模数为B'而不是更大的B'。但它究竟是如何工作的是一个实现细节。