对于某些情况下的大型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”形式的某些特定情况下会出现负值。
我做错了什么?我该如何解决?
答案 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] ... */
}
希望这有帮助!