散列表查找 - 使用完美散列,在C中

时间:2011-09-07 03:38:36

标签: c hashtable perfect-hash

我有一个C语言应用程序,我需要进行表查找。

条目是字符串,所有在运行时开始时都是已知的。该表初始化一次,然后多次查找。该表可以更改,但它基本上就像应用程序重新开始一样。我想这意味着我可以使用完美哈希?可以花一些时间进行哈希表初始化,因为它只发生一次。

将有3到100,000个条目,每个条目都是唯一的,我估计80%的案例将少于100个条目。在这些情况下,简单的天真查找“足够快”。 (==没有人在抱怨)

然而,在有10k +条目的情况下,天真方法的查找速度是不可接受的。在C中为字符串提供良好的基于​​散列表的查找性能的好方法是什么? 假设我没有像Boost / etc这样的第三方商业图书馆。我应该使用什么哈希算法?我该如何决定?

3 个答案:

答案 0 :(得分:4)

生成完美的哈希不是一个简单的问题。有专门负责这项任务的图书馆。 在这种情况下,最受欢迎的可能是CMPH。我没有使用它,但除此之外无法帮助。 gperf是另一个工具,但它需要在编译时知道字符串(你可以通过编译.so和加载来处理它,但是有点矫枉过正)。

但坦率地说,我至少会先尝试二进制搜索。只需使用qsort对数组进行排序,然后使用bsearch进行搜索(或自行滚动)。自C89以来,这两者都是stdlib.h的一部分。

答案 1 :(得分:4)

如果一个天真的(我假设你的意思是线性的)方法可以用于100个条目(因此平均进行50次比较),那么二进制搜索将足以满足100,000个条目(最多需要17次比较)。 / p>

所以我根本不打扰哈希,只是在启动时调整你的字符串表(例如使用qsort),然后使用二进制搜索(例如使用bsearch)来查找条目。

答案 2 :(得分:0)

如果已知(最大)表大小,则具有链接的普通哈希表非常容易实现。每件商品的尺寸开销仅为两个整数。使用合理的散列函数,平均每个查询只需要1.5个探测,这对于100%加载的表。

构建完美哈希只有在数据不变的情况下才可行。一旦它发生变化,你就必须重新计算和重新计算,这比做一些额外的比较更加昂贵。