【问题标题】:Polynomial hash code results in negative numbers?多项式哈希码导致负数?
【发布时间】:2013-10-25 22:50:27
【问题描述】:

对于某些情况下较大的 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”形式的某些特定情况下。

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

【问题讨论】:

    标签: c++ math hash


    【解决方案1】:

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

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

    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] ... */
    }
    

    希望这会有所帮助!

    【讨论】:

    • 使用这个我没有得到负值,但我得到的是最大 int 值的错误。我该如何解决??
    • @user2648875- 你#include &lt;climits&gt;了吗?
    • 是的。我不再得到负值,但我得到了 INT_MAX 的值
    • int hashing::hash(string a) { int i =0; int hvalue = 0;诠释 h = 0; while(a[i]!=NULL) { hvalue = hvalue + (int(a[i]))*power(31,i);我++; } h = hvalue%j;返回 h & INT_MAX; }
    • @user2648875- 您遇到什么具体错误?你能详细说明吗?这似乎在我的系统上运行良好。
    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    相关资源
    最近更新 更多