【问题标题】:good hash function良好的哈希函数
【发布时间】:2012-01-20 23:34:27
【问题描述】:

我一直未能理解哈希函数的设计。我正在经历一个例子。在函数 cmets 中可以看到,为什么要选择 31 作为要相乘的数字。你如何决定?这是随机的还是意味着什么?

unsigned int hash(hash_table_t *hashtable, char *str)
{
    unsigned int hashval;

    /* we start our hash out at 0 */
    hashval = 0;

    /* for each character, we multiply the old hash by 31 and add the current
     * character.  Remember that shifting a number left is equivalent to 
     * multiplying it by 2 raised to the number of places shifted.  So we 
     * are in effect multiplying hashval by 32 and then subtracting hashval.  
     * Why do we do this?  Because shifting and subtraction are much more 
     * efficient operations than multiplication.
     */
    for(; *str != '\0'; str++) hashval = *str + (hashval << 5) - hashval;

    /* we then return the hash value mod the hashtable size so that it will
     * fit into the necessary range
     */
    return hashval % hashtable->size;
}

【问题讨论】:

  • 这被称为 Bernstein 哈希、Torek 哈希,或者简称为“33 次哈希”。我建议从Apache Portable Runtime 阅读 cmets。

标签: c hashcode hash-function


【解决方案1】:

所讨论的散列称为 Bernstein 散列、Torek 散列或简称为“33 倍”散列。它非常受欢迎,因为它简单、速度快,并且使用 English 字符串数据分布得体。

您的 cmets 注意到它实际上是乘以 31,这对您来说似乎是任意的,实际上 有点任意。 Apache Portable Runtime has a comment in their hash algorithm source 指出许多可能的常量都很好用(33 是最常见的)。它们都是奇数且接近 2 的幂,这意味着它们可以很好地转化为移位和加法或减法。

其他一些有助于理解散列的资源:

【讨论】:

  • 我基本上是在思考“什么是设计散列函数的好方法”。现在至少大多数都是反复试验的事实让我松了一口气。我了解 times33 哈希。谢谢
【解决方案2】:

这是关于 65k 视图的哈希函数的讲座。在 YouTube 上:http://www.youtube.com/watch?v=KW0UvOW0XIo

这并不完全是您所要求的,但是您的问题表明您在散列方面的知识是有限的。最好阅读教程或查看演示文稿。

【讨论】:

    猜你喜欢
    • 2016-12-07
    • 2010-11-22
    • 2011-10-27
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多