2016-11-24 60 views
3

我想與另一個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

回答

2

首先,平等運營商肯定是必需的,所以你應該保持它。

讓我們看看你的無序地圖的哈希函數:

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

因爲它是一個無序的地圖,顧名思義,迭代器可以在無序地圖的任何順序按鍵迭代。但是,由於散列函數必須爲相同的密鑰產生相同的散列值,所以這個散列函數在這方面顯然會失敗。

此外,我還希望除了密鑰本身外,散列函數還將包含未定向映射密鑰的值。我想你可能想這樣做 - 對於兩個無序地圖,只要它們的密鑰相同,忽略它們的值就被認爲是相同的密鑰。從問題中不清楚你的期望是什麼,但你可能想要考慮一下。

+0

是的,那是問題,哈希函數沒有爲相同的鍵返回相同的值。它以某種方式逃脫了我的想法。 –

2

使用==比較兩個std::unordered_map對象比較地圖是否包含相同的密鑰。它不會告訴他們是否按照相同的順序包含它們(畢竟這是一張無序的地圖)。但是,您的hashing_func取決於地圖中項目的順序:hash<string>()("ab")hash<string>()("ba")大體上不同。

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