C ++ unordered_map其中key也是unordered_map

时间:2016-11-24 14:22:04

标签: c++ dictionary hash stl unordered-map

我正在尝试使用带有另一个unordered_map的unordered_map作为键(自定义散列函数)。我也添加了一个自定义相同的功能,即使它可能不需要。

代码没有达到我的预期,但我无法对正在发生的事情做出正面或反面。出于某种原因,在执行find()时不会调用相等的函数,这是我所期望的。

unsigned long hashing_func(const unordered_map<char,int>& m) {
    string str;
    for (auto& e : m)
        str += e.first;
    return hash<string>()(str);
}
bool equal_func(const unordered_map<char,int>& m1, const unordered_map<char,int>& m2) {
    return m1 == m2;
}

int main() {

    unordered_map<
        unordered_map<char,int>, 
        string,
        function<unsigned long(const unordered_map<char,int>&)>,
        function<bool(const unordered_map<char,int>&, const unordered_map<char,int>&)>
        > mapResults(10, hashing_func, equal_func);

    unordered_map<char,int> t1 = getMap(str1);
    unordered_map<char,int> t2 = getMap(str2);

    cout<<(t1 == t2)<<endl; // returns TRUE
    mapResults[t1] = "asd";
    cout<<(mapResults.find(t2) != mapResults.end()); // returns FALSE

    return 0;
}

3 个答案:

答案 0 :(得分:2)

使用std::unordered_map比较两个==对象,比较地图是否包含相同的键。它没有什么可以判断它们是否以相同的顺序包含它们(毕竟它是无序的地图)。但是,您的hashing_func取决于地图中项目的顺序:hash<string>()("ab")通常与hash<string>()("ba")不同。

答案 1 :(得分:2)

首先,当然需要使用相等运算符,所以你应该保留它。

让我们看看你的无序地图的哈希函数:

string str;
for (auto& e : m)
    str += e.first;
return hash<string>()(str);

由于它是一个无序映射,根据定义,迭代器可以按任何顺序迭代无序映射的键。但是,由于散列函数必须为同一个密钥生成相同的散列值,因此该散列函数在这方面显然会失败。

此外,除了键本身之外,我还希望散列函数还包括unorderered映射键的值。我想你可能想这样做 - 只要两个无序映射的键是相同的,就会被认为是相同的键,忽略它们的值。从问题中不清楚你的期望是什么,但你可能想要考虑一下。

答案 2 :(得分:0)

一个好的起点是hashing_func为每个地图返回的内容,或者更容易在hashing_func中生成的字符串结构。

这种类型的更明显正确的哈希函数可以是:

unsigned long hashing_func(const unordered_map<char,int>& m) {
    unsigned long res = 0;
    for (auto& e : m)
        res ^ hash<char>()(e.first) ^ hash<int>()(e.second);
    return res;
}