基本上我的程序使用以下格式读取文本文件:
3
chairs
tables
refrigerators
第一行的数字表示要读取的文件中的项目数。
这是我的哈希函数:
int hash(string& item, int n) {
int hashVal = 0;
int len = item.length();
for(int i = 0; i < len; i++)
hashVal = hashVal*37 + item[i];
hashVal %= n;
if(hashVal < 0) hashVal += n;
return hashVal;
}
当我的程序读取上面的文本文件时,它成功了。但当我尝试另一个时:
5
sabel
ziyarah
moustache
math
pedobear
该计划将冻结。不是分段错误或其他任何东西,但它会停止。
有什么想法吗?
编辑:
int n, tableSize;
myFile >> n;
tableSize = generateTableSize(n);
string item, hashTable[tableSize];
for(int i = 0; i < tableSize; i++)
hashTable[i] = "--";
while(myFile >> item && n!=0) {
int index = hash(item,tableSize);
if(hashTable[index] == "--")
hashTable[index] = item;
else {
int newIndex = rehash(item,tableSize);
while(hashTable[newIndex] != "--") {
newIndex = rehash(item,tableSize);
}
hashTable[newIndex] = item;
}
n--;
}
int rehash(string item, int n) {
return hash(item,n+1);
}
答案 0 :(得分:4)
代码冻结,因为它以无限循环结束:
int index = hash(item,tableSize);
if(hashTable[index] == "--")
hashTable[index] = item;
else {
int newIndex = rehash(item,tableSize);
while(hashTable[newIndex] != "--") {
newIndex = rehash(item,tableSize);
}
hashTable[newIndex] = item;
}
您不断重新计算索引,但不更改输入参数,因此输出保持不变,因此会再次重新计算。
在上面的代码中计算newIndex
,基于与使用不同计算器函数计算的index
相同的输入,因此很可能它将具有与第一次不同的值,然而,新指数也被占用。所以我们这次使用与之前相同的函数再次重新计算newIndex
,使用完全相同的输入,再次给出完全相同的输出。您在哈希表中查找相同的索引,这仍然是您上次执行时的相同值,因此您再次使用相同的输入参数重新计算,给出相同的输出,您在哈希表中查找再一次,等等。
你没有看到前三行的原因是你没有碰撞(或者至少只有一次碰撞,这意味着从newIndex
计算的rehash
功能第一次很有用。)
解决方案不是增加表格大小(因为增加表格大小,最多会降低碰撞的机会,这可能是好的,但不会完全解决你的问题),但要么改变您的函数的输入,因此您获得不同的输出,或更改哈希表结构。
我总是发现Sedgewick关于algorithms in C++的书很有用,有一章讨论哈希。
可悲的是,我手边没有我的C ++算法副本,所以我不能告诉你Sedgewick是如何解决它的,但我建议你解决问题的简单教育目的,首先简单地将索引递增1直到你在哈希表中找到一个空闲插槽。