hash_map即使在键相等时也保存每个键/值对

时间:2010-11-17 04:03:01

标签: c++ hashmap key-value

嘿伙计们,我正在使用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 . . .

为什么会这样?我每次尝试打印哈希值,但哈希值是相同的。

3 个答案:

答案 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),其中compTraits类型的存储对象,您可以在构造对象hash_comp时指定该对象。对于默认的Traits参数类型less<Key>,排序键的值永远不会减少。

因此,虽然将比较函数更改为返回str1 != str2似乎对您的测试有效,但它并不正确。在两个不同字符串碰巧具有相同哈希码的情况下,它会使hash_map混淆。