c++ 找不到元素是 unordered_set 具有相同的散列
c++ cannot find element is unordered_set with the same hash
我有 unordered_set 个向量的自定义哈希函数< 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 相同的向量时,我得到错误:
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,find
方法应该 return 为真,当我尝试找到 v2。但事实并非如此。
有人能解释一下我的推理有什么问题吗?
I assume that if two elements in unordered_set have the same hash then if I have v1 in my unordered_set, find method should return true, when I try to find v2.
该假设不正确,相同的哈希值并不意味着对象相等。
unordered_map
使用相等谓词来确定键相等性(默认 std::equal_to
)。
哈希不是一切,您在这里看到的是一种冲突。
这里两个std::vector<int>
的hash值是一样的,但是hash计算出来后,std::unordered_map
实际上会用operator==
来检查元素是否相等,在这种情况下失败,无法找到元素。
冲突在 HashMaps 中是很正常的事情,如果不提供自定义 operator==
。
如果您恰好需要唯一标识符但不自动比较值,您可以使用 (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;
那么你应该得到你期望的结果
我有 unordered_set 个向量的自定义哈希函数< 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 相同的向量时,我得到错误:
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,find
方法应该 return 为真,当我尝试找到 v2。但事实并非如此。
有人能解释一下我的推理有什么问题吗?
I assume that if two elements in unordered_set have the same hash then if I have v1 in my unordered_set, find method should return true, when I try to find v2.
该假设不正确,相同的哈希值并不意味着对象相等。
unordered_map
使用相等谓词来确定键相等性(默认 std::equal_to
)。
哈希不是一切,您在这里看到的是一种冲突。
这里两个std::vector<int>
的hash值是一样的,但是hash计算出来后,std::unordered_map
实际上会用operator==
来检查元素是否相等,在这种情况下失败,无法找到元素。
冲突在 HashMaps 中是很正常的事情,如果不提供自定义 operator==
。
如果您恰好需要唯一标识符但不自动比较值,您可以使用 (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;
那么你应该得到你期望的结果