这是短字符串的良好哈希函数吗?

时间:2018-09-26 13:01:30

标签: c++ string hash

对于10至50个字符的字符串:

double hash(const std::string & str)
{
    double result = 0;
    int n=str.length();
    for(int i=0;i<n;i++)
    {
        result += (str[i] - '@')*pow(256.0,i);
    }
    return result;
}

可以在生产代码中使用它吗?

  • 通过ILP与std :: hash一起使用时,可提高哈希的总吞吐量
  • 正确性/唯一性
  • 可扩展性

通过评论的新版本:

double hash(const std::string & str)
{
    double result = 0;
    int n=str.length();

    // maybe using multiple adders to do concurrently multiple chars
    // since they are not dependent
    for(int i=0;i<n;i++)
    {
        result += lookupCharDoubleType[str[i]]*lookupPow[i];
    }
    return result;
}

另一个版本的另一条评论:

double hash(const std::string & str)
{
    double result = 0;
    int n=str.length();

    for(int i=0;i<n;i++)
    {
        result = result * 256.0 + lookupCharDoubleType[str[i]];
    }
    return result;
}

1 个答案:

答案 0 :(得分:4)

  

这是短字符串的良好哈希函数吗?

否,对于唯一性而言,这不是一个很好的哈希值。您基本上是将字符串映射到double上。对于长度为50个字符的字符串,您将获得一个256 ^^ 50左右的值,即2.58e120。恰好在双精度数的范围(即1.7e308)之内,但是您必须了解double并不完全代表数字-毕竟只有8个字节。

您的代码将字符串映射到double,就好像字符是以256为基数的数字,第一个字符是最低有效数字:

字符串hello的映射如下:

'h' * 256^^0 + 'e'*256^^1 + 'l' * 256^^2 + 'l' * 256^^3 + 'o' * 256^^4

对于大于几个字节的字符串,最后一个字符将是结果中最重要的部分,而所有其他字符将被完全删除,因为double不具有精度代表所有这些位。

最终结果是您的哈希函数将只考虑最后几个字符。只要字符串中的任何个字符发生变化,一个好的哈希函数都应发生变化,因此相似但不完全相同的字符串极不可能具有相同的哈希值。使用您的函数,只要最后几个字符相同,哈希值就可能相同。