STL 的 hash_map 中的碰撞检测
Posted
技术标签:
【中文标题】STL 的 hash_map 中的碰撞检测【英文标题】:Collision detection in STL's hash_map 【发布时间】:2010-06-19 05:23:16 【问题描述】:我必须为函数指针(作为值)创建 C 函数名称(作为键)的查找表。我正在考虑使用 STL 的 hash_map
容器,因为哈希表的访问时间是 O(1)
。有什么好的散列函数吗?目前我使用(31*H + c)
作为我的哈希函数。
另外,STL 的hash_map
是否会处理冲突,或者我必须在我的代码中处理它们?如果可能,请举一些例子。
我目前正在处理的示例代码
#include <iostream>
#include <ext/hash_map>;
using namespace std;
using namespace __gnu_cxx;
namespace __gnu_cxx
#ifndef __HASH_STRING__
#define __HASH_STRING__
template <>
struct hash<string>
size_t operator() (const std::string& s) const
size_t h = 0;
std::string::const_iterator p, p_end;
for(p = s.begin(), p_end = s.end(); p != p_end; ++p)
h = 31 * h + (*p);
return h;
;
#endif
;
int main()
hash_map<string, int> months;
months["january"] = 1;
months["february"] = 2;
months["march"] = 3;
months["april"] = 4;
months["may"] = 5;
months["june"] = 6;
months["july"] = 7;
months["august"] = 8;
months["september"] = 9;
months["october"] = 10;
months["november"] = 11;
months["december"] = 12;
return 0;
【问题讨论】:
键中的函数名称?hash_map
是一个旧实现(顺便说一下,标准库没有映射/无序映射)。使用现代哈希映射,例如 boost 的 unordered_map
。它完成了所有的哈希处理,你只需插入并继续你的生活。对于它的价值,hash_map
如果没有实现哈希映射,那将是相当糟糕的。 :)(即:是的,它应该处理冲突,这是哈希映射的工作。)
【参考方案1】:
假设您拥有完整的 STL,它实际上包含一个散列函数 hash<T>
,它包含的形式是 suitable for a few different key types,包括 char*(C 字符串)。我不知道它的性能细节,但 STL 通常被设计为具有大多数应用程序可接受的性能。
至于碰撞,由hash_map
处理,你不必担心。
【讨论】:
完整的 STL 是什么意思?我将如何检查我是否获得了完整的 STL?我还添加了我目前正在编写的示例代码。 @Ravi:STL 不是实际 C++ 标准的一部分(尽管它的一个子集已合并到 C++ 标准库中)。它的一些内容不时出现在编译器中,但通常是不完整的,有时以令人惊讶的方式出现。不过,由于您似乎正在使用 GCC/g++,我可以肯定地说您应该拥有hash<T>
。
澄清一下,C++ 有一个标准库。说“STL”意味着“标准库”是用词不当。它可能意味着标准库、标准库的模板部分、原始 STL 或其他东西。 Ravi 的意思可能是“标准库”,而我认为 Nicholas 的意思是“SGI STL”。
@Ravi:这可能是“一个”定义,但不是“那个”定义。 C++ 没有定义“STL”或“标准模板库”。
@Nicholas Knight & @GMan:这里的 C++ 标准和 STL 之间实际上有一个有效的区别——C++ 标准不包含任何类型的 hash_map
类,所以任何人都在谈论这个类特定于特定的实现。 (请注意,即使将哈希数据结构合并到下一个标准中,它们也称为unordered_set
和unordered_map
等,而不是hash_X
。【参考方案2】:
您不需要处理冲突。另外,我认为 std::hash 已经定义了,所以你不需要担心哈希函数。
【讨论】:
以上是关于STL 的 hash_map 中的碰撞检测的主要内容,如果未能解决你的问题,请参考以下文章