多项式哈希码导致负数

Polynomial hash code results in negative numbers?

本文关键字:哈希码 多项式      更新时间:2023-10-16

对于大j,在某些情况下,下面的哈希函数返回负值。

int hashing::hash(string a)
{
    int i = 0;
    int hvalue = 0;
    int h =0 ;
    while(a[i]!=NULL)
    {
        hvalue = hvalue + (int(a[i]))*pow(31,i);
        i++;
    }
    h = hvalue%j;
    return h;
}

这怎么可能?我该如何纠正它?

在上面的代码中,j 是使用文件大小计算的质数。负值出现在字符串形式为"s"的某些特定情况下。

我做错了什么?我该如何解决它?

请记住,int的范围有限,并且(通常)是一个有符号值。这意味着,如果超过int的最大可能值,它将环绕并可能变为负数。

有几种方法可以解决这个问题。首先,您可以切换到使用 unsigned int s 来保存哈希代码,这些代码永远不会是负数,并且在环绕时会表现良好。或者,如果您仍想使用 int s,您可以通过执行以下操作来屏蔽符号位(数字前面使值为负的位):

return (hvalue & INT_MAX) % j;

(在这里,INT_MAX<climits> 中定义)。这将确保您的值为正数,尽管您从哈希代码中丢失了一些内容,这对于大型数据集可能会导致更多的聚类。在 Mod 之前执行&的原因是您希望在使用 Mod 之前确保该值为正数,否则您将溢出存储桶数量。

编辑:你的逻辑中也有一个严重的错误。 此循环不正确:

while(a[i]!=NULL) {
    ...
}

C++ 样式的字符串不以 null 结尾结尾,因此不能保证在读取超过字符串末尾后停止此操作。尝试将其更改为阅读

for (int i = 0; i < a.length(); i++) { 
    /* ... process a[i] ... */
}

希望这有帮助!