字符串的哈希函数不能处理某些字符串?

时间:2015-04-21 12:17:53

标签: c++ string hash

基本上我的程序使用以下格式读取文本文件:

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);
}

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直到你在哈希表中找到一个空闲插槽。