嘿伙计们,我正在使用hash_map将字符串相互关联,使用以下代码:
#include <string>
#include <iostream>
#include <hash_map>
using namespace std;
using namespace stdext;
struct StrCompare : public stdext::hash_compare<string> {
unsigned int operator()(const string str) const {
unsigned int hash = 0;
unsigned int len = str.length();
for (unsigned int i = 0; i < len; i++)
hash = 31 * hash + str[i];
return hash;
}
bool operator()(const string str1, const string str2) const {
return str1 == str2;
}
};
int main() {
hash_map<string, string, StrCompare> m;
m["asdf"] = "fe";
m["asdf"] = "asdf";
for (hash_map<string, string, StrCompare>::iterator i = m.begin(); i != m.end(); ++i)
cout << i->first << " " << i->second << endl;
system("PAUSE");
}
问题是输出是:
asdf asdf
asdf fe
Press any key to continue . . .
为什么会这样?我每次尝试打印哈希值,但哈希值是相同的。
答案 0 :(得分:2)
hash_map
没有进入C ++ 0x的原因之一是存在许多冲突的实现,而且几乎没有可靠的规范。
我会切换到C ++ 0x中接受的内容。 std::unordered_map
可能有一个冗长,笨拙的名字,但语义是明确定义的;它将不存储重复的密钥(为此您使用std::unordered_multimap
代替)。
答案 1 :(得分:0)
哦,显然我正在使用
bool operator()(const string str1, const string str2) const
功能错误。而不是
bool operator()(const string str1, const string str2) const {
return str1 == str2;
}
应该是
bool operator()(const string str1, const string str2) const {
return str1 != str2;
}
答案 2 :(得分:0)
从您的示例的一些细节来看,您似乎正在使用MSVC。 Microsoft的hash_map
使用与散列函数结合使用的比较函数,以便为散列到相同值的键提供排序。这与SGI的hash_map
规范不同。具体来说(来自http://msdn.microsoft.com/en-us/library/1s1byw77.aspx):
对于序列中
_Key1
之前的Key
类型的任何值_Key2
,并且具有相同的哈希值(哈希函数返回的值),hash_comp(_Key2, _Key1)
为false 。该函数必须对类型Key
的值施加总排序。 hash_compare提供的函数返回comp(_Key2, _Key1)
,其中comp
是Traits
类型的存储对象,您可以在构造对象hash_comp
时指定该对象。对于默认的Traits
参数类型less<Key>
,排序键的值永远不会减少。
因此,虽然将比较函数更改为返回str1 != str2
似乎对您的测试有效,但它并不正确。在两个不同字符串碰巧具有相同哈希码的情况下,它会使hash_map
混淆。