多项式哈希码导致负数?

时间:2013-10-25 22:50:27

标签: c++ math hash

对于某些情况下的大型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”形式的某些特定情况下会出现负值。

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

1 个答案:

答案 0 :(得分:1)

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

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

return (hvalue & INT_MAX) % j;

(此处INT_MAX定义了<climits>。这将确保您的值是积极的,尽管您从哈希代码中丢失了一些,这可能会导致大型数据集导致更多的群集。在mod之前执行&的原因是你想在获取mod之前确保值为正,否则你将溢出桶的数量。

编辑:您的逻辑中也存在严重错误。这个循环不正确:

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

C ++ - 样式字符串不以空值终止,因此一旦您读取字符串末尾,就不能保证停止。尝试将其更改为阅读

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

希望这有帮助!