用C++实现哈希表冲突的避免与解决
Hash table implementation collision avoidance and resolution in C++
我发现了这个简单的实现:
http://www.onextrabit.com/view/502c152965e7d250c5000001
然而,它没有任何共谋规避。所以我修改成这样:
#include <iostream>
#include <sstream>
using namespace std;
template <typename ElemType>
class HashTable {
private:
// data
ElemType* hashData;
// hash table size
int tableSize;
// djb2 hash function
int hashing(string key) {
int hash = 5381;
for (int i = 0; i < key.length(); i++)
hash = ((hash << 5) + hash) + (int)key[i];
return hash % tableSize;
}
public:
HashTable(int size) {
tableSize = size;
// init hash table data given table size
hashData = new ElemType[tableSize];
}
~HashTable() {
delete[] hashData;
}
void set(string key, const ElemType& value) {
int index = hashing(key);
int i = 0;
for (;(hashData[index] != (ElemType)NULL) && (i <= tableSize); i++) {
index = (index + 1) % tableSize;
}
if (i > tableSize) {
cout << "No empty bucket!" << endl;
return ;
}
hashData[index] = value;
}
string get(string key) {
int index = hashing(key);
stringstream result;
result << hashData[index];
int i = 0;
for (;(hashData[++index] != (ElemType)NULL) && (i <= tableSize); i++) {
result << " or " << hashData[index];
index %= tableSize;
}
return result.str();
}
};
int main() {
HashTable<int> hash(50);
hash.set("Hello", 12);
hash.set("World", 22);
hash.set("Wofh", 25);
for (int i = 1; i < 10; i++) {
hash.set("Wofh", i);
}
cout << "Hello " << hash.get("Hello") << endl;
cout << "World " << hash.get("World") << endl;
cout << "Wofh " << hash.get("Wofh") << endl;
return 0;
}
这是我第一次实现哈希表。现在,"World"answers"Wofh"从hashing()
函数中得到了相同的结果。很明显,这导致了一场共谋。然而,当我想检索"世界"时,它显示了所有串通的价值观。我的问题是,有没有一种方法可以只使用线性探测来显示"世界"数字(22)?
每个表条目都需要包含一组与哈希匹配的键/值对。然后,在查找表条目后,您需要在该集合中搜索所请求的关键字。
如果碰撞很罕见,那么一个简单的成对向量可能就足够了。如果它们的频率足够高,以至于搜索太慢,并且无法通过放大表或使用更好的has函数来降低频率,那么可以考虑对向量进行排序,并使用二进制搜索,或者使用std::map
或另一个哈希表(具有不同的哈希函数)来存储冲突元素。
当然,除非这是一个学习练习,否则你通常只会使用std::unordered_map
(或者Boost、TR1或STL等价物,如果你不能使用C++11库的话)。
此外,在设计管理内存或其他资源的类时,请始终记住"三条规则"。如果有人试图复制你的类,你的类就会出错。
相关文章:
- 如何解决GTest和LibTorch联动冲突
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- 如何解决两个不使用命名空间的第三方库之间的类名冲突?
- 如何解决此C++访问冲突问题
- GNUMakefile 和 gcc:解决冲突"-std=c++"需求的顺序
- 如何解决头文件中的变量冲突?
- Eigen SparseLU解决错误读取访问冲突,这>m_sup_to_col被0x111011101110112
- LR解析器如何解决歧义和冲突
- 如何解决GMP的32位和64位库之间的冲突
- C++将冲突解决映射为javaHashMap
- C++STL如何unordered_map解决冲突?
- 如何解决"sprintf"的冲突类型?
- 尝试解决链接器警告:默认库'MSVCRT'与使用其他库冲突
- 解决LNK4098:默认库'MSVCRT'冲突 (DCMTK) 和 LNK2038/LNK2005
- 包括文件冲突解决方案
- 用于分组以解决冲突的算法
- 如何解决调用 dll 方法时的访问冲突写入位置
- 如何解决编译器枚举重新声明冲突
- 解决运行时库冲突的好方法是什么?
- 在C++中使用多个静态库解决冲突