什么是英语单词的好散列函数?

Posted

技术标签:

【中文标题】什么是英语单词的好散列函数?【英文标题】:What's a good hash function for English words? 【发布时间】:2011-12-03 18:20:48 【问题描述】:

我有一长串英语单词,我想对它们进行哈希处理。什么是好的散列函数?到目前为止,我的散列函数将字母的 ASCII 值相加,然后对表格大小取模。我正在寻找高效且简单的东西。

【问题讨论】:

查看这里cse.yorku.ca/~oz/hash.html Good Hash Function for Strings 和 What is a good 64bit hash function in Java for textual strings? 的可能重复 可以在其他 stackexchange 网站上找到这个问题的好答案:softwareengineering.stackexchange.com/questions/49550/… 【参考方案1】:

简单地将字母相加并不是一个好的策略,因为排列会产生相同的结果。

这个 (djb2) 非常流行,可以很好地处理 ASCII 字符串。

unsigned long hashstring(unsigned char *str)

    unsigned long hash = 5381;
    int c;

    while (c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;

更多信息here。

如果您需要更多替代方案和一些性能指标,请阅读here。

补充:这些是一般散列函数,其中输入域是事先不知道的(除了一些非常一般的假设:例如,上面的内容与 ascii 一起工作得更好一些输入),这是最常见的情况。如果您有一个已知的受限域(固定输入集),您可以做得更好,请参阅 Fionn 的回答。

【讨论】:

不,它只是一个“种子”,相当随意。 @MikeG:这是“种子”或起始值。这个通常称为“Times 33”哈希。 @sixlettervariables 我在哪里指定表格长度?如果它返回的数字大于我的表格怎么办? 理论上它可以返回任何有效的unsigned long值。由您来操作散列以适应您的约束。 @MikeG:通常,您不会在哈希算法中指定表大小(如果您不知道,请使用已经制作的表......)。该表可能会根据项目的数量而增长或缩小(对于良好的实现),因此您只需计算哈希值,然后将哈希值取模当前大小即可知道将其放入哪个存储桶中。【参考方案2】:

也许这样的事情会帮助你:http://www.gnu.org/s/gperf/

它为输入域生成一个优化的散列函数。

【讨论】:

【参考方案3】:

如果您不需要加密安全,我建议使用 Murmur Hash。它速度极快,并且具有很高的扩散性。易于使用。

http://en.wikipedia.org/wiki/MurmurHash

http://code.google.com/p/smhasher/wiki/MurmurHash3

如果您确实需要加密安全哈希,那么我建议通过 OpenSSL 进行 SHA1。

http://www.openssl.org/docs/crypto/sha.html

【讨论】:

MurmurHash+1,你知道 CityHash 和 MurmurHash 的比较吗?我听说过两者的好消息,但从未见过全面的比较,只是有一些轶事。【参考方案4】:

有点晚了,但这里有一个哈希函数,对于下面的 64 位版本,冲突率极低,并且 ~ 几乎 ~ 对 32 位版本同样好:

uint64_t slash_hash(const char *s)
//uint32_t slash_hash(const char *s)

    union  uint64_t h; uint8_t u[8];  uu;
    int i=0; uu.h=strlen(s);
    while (*s)  uu.u[i%8] += *s + i + (*s >> ((uu.h/(i+1)) % 5)); s++; i++; 
    return uu.h; //64-bit
    //return (uu.h+(uu.h>>32)); //32-bit

哈希数也非常均匀地分布在可能的范围内,没有我可以检测到的聚集 - 这仅使用随机字符串进行检查。 [编辑]还针对从本地文本文件中提取的单词以及 LibreOffice 词典/同义词库单词(英语和法语 - 超过 97000 个单词和结构)进行了测试,在 64 位中出现 0 次冲突,在 32 位中出现 1 次冲突-位:)

(还与 FNV1A_Hash_Yorikke、djb2 和 MurmurHash2 在同一组上进行比较:Yorikke 和 djb2 表现不佳;slash_hash 在所有测试中都略好于 MurmurHash2)

【讨论】:

这是一个合理的哈希函数。我建议避免使用未命名的工会。 -->> union uint64_t h; uint8_t u[8]; uu; 和代码中的类似更改 -->> uu.h=strlen(s); ... uu.u[i%8] += ...

以上是关于什么是英语单词的好散列函数?的主要内容,如果未能解决你的问题,请参考以下文章

专业背单词的好软件

专业背单词的好软件

英式英语和美式英语的单词一样吗

请问有没有啥方法能记住cucumber这个单词

英式英语和美式英语有啥区别?

"c"打头"c"打头的都有啥英语单词?????????????????????????????????