c++找不到具有相同哈希的无序集合元素

c++ cannot find element is unordered_set with the same hash

本文关键字:无序 集合 元素 哈希 找不到 c++      更新时间:2023-10-16

我有一个自定义的散列函数,用于向量的无序集合<int>:

struct VectorHash {
int operator()(const vector<int> &V) const {
int hsh=V[0] + V[1];
return  hash<int>()(hsh);
}};

对于两个这样的向量,我有相同的散列,等于3:

vector<int> v1{2,1};
vector<int> v2{1,2};

但是,当我试图在unordered_set中插入第一个向量v1,然后通过哈希检查我的unordered.set中是否有与v2相同的向量时,我得到了false:

std::unordered_set<std::vector<int>, VectorHash> mySet;
mySet.insert(v1); 
if(mySet.find(v2) == mySet.end())
cout << "didn't find" << endl;
Output:  "didn't find"

我假设如果unordered_set中的两个元素具有相同的散列,那么如果我的unordered.set中有v1,当我试图找到v2时,find方法应该返回true。但事实并非如此。

有人能解释一下我的推理错在哪里吗?

哈希不是一切,您在这里看到的是一个碰撞。

两个std::vector<int>在这里具有相同的哈希值,但在计算哈希后,std::unordered_map实际上会使用operator==来检查元素的相等性,在这种情况下失败,并且找不到元素。

在HashMaps中,冲突是一件正常的事情,如果不提供自定义operator==,您在这里就无能为力。

我假设如果无序集合中的两个元素具有相同的哈希,那么如果我的无序集合中有v1,当我尝试查找v2时,find方法应该返回true。

这个假设是不正确的,相同的散列并不意味着对象是相等的。

unordered_map使用相等谓词来确定密钥相等(默认情况下为std::equal_to(。

如果您碰巧想要唯一的标识符,但不自动比较值,则可以使用(unordered_)map<int, vector<int>>并使用VectorHash函数生成int键:

unordered_map<int, vector<int>> map;
int key=V[0] + V[1]
map[key] = V;

如果你想让这两个元素匹配,你也需要为unordered_set提供一个比较器,你可以这样做:

struct VectorComparator {
bool operator()(const std::vector<int> & obj1, const std::vector<int> & obj2) const
{
if ((obj1[0] + obj1[1]) == (obj2[0] + obj2[1]))
return true;
return false;
}
};

并像这个一样创建您的unordered_set

std::unordered_set<std::vector<int>, VectorHash, VectorComparator> mySet;

然后你应该得到你期望的结果