C++ unordered_map其中键也unordered_map

问题描述:

我想与另一个unordered_map作为一个键(自定义哈希函数)使用unordered_map。我也添加了一个自定义的平等功能,即使它可能不需要。C++ unordered_map其中键也unordered_map

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

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; 
} 
+1

看看你的哈希函数为两张图返回什么 – Caleth

首先,平等运营商肯定是必需的,所以你应该保持它。

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

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

因为它是一个无序的地图,顾名思义,迭代器可以在无序地图的任何顺序按键迭代。但是,由于散列函数必须为相同的密钥产生相同的散列值,所以这个散列函数在这方面显然会失败。

此外,我还希望除了密钥本身外,散列函数还将包含未定向映射密钥的值。我想你可能想这样做 - 对于两个无序地图,只要它们的密钥相同,忽略它们的值就被认为是相同的密钥。从问题中不清楚你的期望是什么,但你可能想要考虑一下。

+0

是的,那是问题,哈希函数没有为相同的键返回相同的值。它以某种方式逃脱了我的想法。 –

使用==比较两个std::unordered_map对象比较地图是否包含相同的密钥。它不会告诉他们是否按照相同的顺序包含它们(毕竟这是一张无序的地图)。但是,您的hashing_func取决于地图中项目的顺序:hash<string>()("ab")hash<string>()("ba")大体上不同。

一个很好的开始就是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; 
}