代码之家  ›  专栏  ›  技术社区  ›  Sint

做一个完美的散列(所有连续的桶都满了),gperf还是其他选择?

  •  3
  • Sint  · 技术社区  · 15 年前

    假设我想构建一个完美的哈希表来查找一个数组,其中预定义的键是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加char值查找。不知怎么的,在我的脑海里,我想象着一个奇形怪状的功能…:)

    如果我只想要12个桶(也就是说我不想跳过未使用的桶)怎么办?对于这样的小集合,这真的不重要,但是当我有1000个预定义的键并且一行正好需要1000个桶时?

    我们能找到一种确定的方法来做到这一点吗?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Remo.D    15 年前

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

    当我第一次看《极简完美》时,我发现了一些非常有趣的读物。 CiteseerX 但我抵制了自己尝试编写其中一个解决方案的诱惑。我知道我最终会得到一个比gperf或cmph差的解决方案,或者,即使假设这个解决方案是可比的,我也不得不花很多时间在它上面。

        2
  •  6
  •   user181548    15 年前

    我对这个问题的答案很感兴趣,通过搜索 gperf . 我尝试了gperf,但在一个大的输入文件上速度很慢,因此似乎不适合。我试过CMPH,但不满意。它需要构建一个文件,然后在运行时加载到C程序中。此外,程序是如此脆弱(在任何类型的错误输入上都会出现“分段错误”崩溃),以至于我不相信它。进一步的谷歌搜索让我 this page 向前 mph . 我下载了MPH,发现它很不错。它有一个可选的程序来生成一个名为“emitc”的C文件,并使用它

     mph < systemdictionaryfile | emitc > output.c
    

    几乎可以立即工作(用大约200000个单词的字典工作几秒钟),并创建了一个可以正常编译的C文件。我的测试也表明它是有效的。不过,我还没有测试哈希算法的性能。