std :: tuple的自定义哈希不适用于unordered_set

问题描述 投票:0回答:1

希望您能帮助我了解我的代码有什么问题。

[基本上,我需要一个unordered_set的元组,但是每次我调用insert函数时,我都会看到即使散列相同,也会插入该元组,这意味着我在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?我期望只有一个。

问候

c++ c++11 hash unordered-set
1个回答
0
投票

两个不相等的元素具有相同的哈希值(一种称为“哈希冲突”的情况,这是完全正常的。毕竟,有无数个字符串,但是size_t中只能表示有限数量的值。观察到std::unordered_set需要两个单独的模板参数-一个用于计算哈希,另一个用于检查两个元素是否相等。

如果要将make_tuple(1, 2, 3)make_tuple(1, 3, 2)视为等效,除了合适的散列实现之外,还需要将合适的相等比较实现作为std::unodered_set的第三个模板参数传递。

简而言之:相等的元素必须散列为相同的值,但反之则不成立-散列为相同值的元素不一定相等。

© www.soinside.com 2019 - 2024. All rights reserved.