std::tuple 的自定义哈希不适用于unordered_set
Custom hash for std::tuple doesn't work with unordered_set
我希望你能帮助我理解我的代码出了什么问题。
基本上我需要一unordered_set元组,但是每次调用插入函数时,我都会看到即使哈希相同,也会插入元组,这意味着我在unordered_set中有具有相同哈希的元组。为了更清楚,让我在这里分享一段代码。
所以,这就是我的例子:
#include <iostream>
#include <tuple>
#include <unordered_set>
using namespace std;
using namespace testing;
struct MyHash {
size_t operator()(const tuple<int, int, int>& t) const
{
auto [num1, num2, num3] = t;
vector<int> v(3);
v[0] = num1;
v[1] = num2;
v[2] = num3;
sort(v.begin(), v.end());
string key = to_string(v[0]) + "|" + to_string(v[1]) + "|" + to_string(v[2]);
auto hashValue = hash<string>()(key);
cout << "Hash value for " << key << "= " << hashValue << endl;
return hashValue;
}
};
int main(int argc, char** argv)
{
unordered_set<tuple<int, int, int>, MyHash> s;
s.insert(make_tuple(1, 2, 3));
s.insert(make_tuple(1, 3, 2));
s.insert(make_tuple(3, 2, 1));
cout << "Amount of items = " << s.size() << endl;
}
这是我得到的输出:
Hash value for 1|2|3= 12066275531359578498
Hash value for 1|2|3= 12066275531359578498
Hash value for 1|2|3= 12066275531359578498
Amount of items = 3
为什么如果每个条目的哈希值相同,则插入的项目量为 3?我期待只有一个。
问候
两个不相等的元素具有相同的哈希值是完全正常的(这种情况称为"哈希冲突"(。毕竟,有无限数量的字符串,但只有有限数量的值可以在size_t
中表示。请注意,std::unordered_set
采用两个单独的模板参数 - 一个用于计算哈希,另一个用于检查两个元素是否相等。
如果要将make_tuple(1, 2, 3)
和make_tuple(1, 3, 2)
视为等效,除了合适的哈希实现外,还需要传递合适的相等比较实现作为std::unodered_set
的第三个模板参数。
简而言之:相等的元素必须散列到相同的值,但反之则不然 - 散列到相同值的元素不一定相等。
相关文章:
- 为什么我无法更改"set<set>"循环中的值<int>
- 对于set上的循环-获取next元素迭代器
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 如何使用set实现无序数据结构?
- 使用运算符调用 void 函数时出错<set>
- 修改"std::set"中用户定义类型的值
- 生成提升::hana::set 的常量表达式问题
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- 重构使用动态强制转换的 std::set 的比较运算符
- set::find 查找不存在的元素
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- 将 std:set<int32_t> 复制到 std::set <uint32_t>的好方法
- 错误 C2676:std::set::const_iterator 没有运算符 + 函数?
- std::set 是否将对象连续存储在内存中?
- 是否有一个 std::set 函数来确定不超过数字 x 的最大元素?
- google test PrintTo for std::set<std::string>