制作一个完美的哈希(所有连续的桶满),gperf或替代品?

时间:2009-11-20 14:02:58

标签: c hashtable gnu lookup-tables

假设我想构建一个完美的哈希表,用于查找预定义键为12个月的数组,因此我希望

hash("January")==0
hash("December")==11

我通过gperf运行我的月份名称并获得了一个很好的哈希函数,但它似乎给出了16个桶(或者更确切地说是16个)!

#define MIN_HASH_VALUE 3
#define MAX_HASH_VALUE 18
/* maximum key range = 16, duplicates = 0 */

查看生成的gperf代码,其哈希函数代码从256大小的表中执行len plus char查找的简单返回。不知何故,在我脑海中,我想象一个看上去很奇怪的功能...... :)

如果我想要12个桶(我不想跳过未使用的桶)怎么办?对于这样的小套装,它真的没关系,但是当我有1000个预定义的键并且连续需要1000个桶时?

可以找到确定性的方法吗?

2 个答案:

答案 0 :(得分:6)

我对这个问题的回答很感兴趣通过搜索gperf找到它。我试过gperf,但是在一个大的输入文件上它很慢,因此看起来不合适。我试过cmph,但我对它并不满意。它需要构建一个文件,然后在运行时将其加载到C程序中。此外,该程序是如此脆弱(在任何类型的错误输入上与“分段错误”崩溃),我不相信它。进一步的Google搜索引导我this page,然后转到mph。我下载了mph,发现它非常好。它有一个可选程序来生成一个名为“emitc”的C文件,并像

一样使用它
 mph < systemdictionaryfile | emitc > output.c

几乎立即工作(几秒钟,带有大约200,000个单词的字典)并创建了一个可以编译的工作C文件,没有任何问题。我的测试也表明它有效。但我还没有测试过哈希算法的性能。

答案 1 :(得分:4)

我知道的唯一替代gperf的是cmph:http://cmph.sourceforge.net/但是,正如杰罗姆在评论中所说,拥有16个水桶可以为你提供一些速度优势。

当我第一次看到最小的完美播放时,我在CiteseerX找到了非常有趣的读物,但我拒绝尝试自己编写其中一种解决方案。我知道我最终会得到一个关于gperf或cmph的劣质解决方案,或者即使假设解决方案具有可比性,我也不得不花费大量时间在它上面。