哈希表查找 - 具有完美的哈希,在 C
Posted
技术标签:
【中文标题】哈希表查找 - 具有完美的哈希,在 C【英文标题】:Hash Table lookup - with perfect hash, in C 【发布时间】:2011-11-11 19:39:40 【问题描述】:我有一个 C 语言应用程序,我需要在其中进行表查找。
条目是字符串,所有在运行时开始时都是已知的。该表被初始化一次,然后多次查找。表格可以更改,但基本上就像应用程序重新开始一样。我认为这意味着我可以使用完美哈希?可以花一些时间来初始化哈希表,因为它只发生一次。
将有 3 到 100,000 个条目,每个条目都是唯一的,我估计 80% 的案例的条目少于 100 个。在这些情况下,简单的简单查找“足够快”。 (== 没有人抱怨)
但是,在有 10k+ 个条目的情况下,幼稚方法的查找速度是不可接受的。为 C 中的字符串提供良好的基于哈希表的查找性能的好方法是什么? 假设我没有像 Boost/etc 这样的第 3 方商业库。我应该使用什么哈希算法?我该如何决定?
【问题讨论】:
gnu.org/s/gperf ? 还有cmph.sourceforge.net 【参考方案1】:生成完美的哈希并不是一个简单的问题。有专门用于这项任务的图书馆。 在这种情况下,最受欢迎的可能是CMPH。虽然我没有使用过它,但除此之外我无能为力。 gperf 是另一个工具,但它要求在编译时知道字符串(您可以通过编译 .so 并加载来解决它,但有点矫枉过正)。
但坦率地说,我至少会先尝试使用二分搜索。只需使用qsort
对数组进行排序,然后使用bsearch
进行搜索(或自己滚动)。自 C89 以来,这两个都是 stdlib.h
的一部分。
【讨论】:
它们也可用于 ANSI C ( C89 )。 对。当我有可用的 BSD 时,不知道为什么要查看 Linux 手册页。 :) 好电话,谢谢 Per。我让问题变得比它需要的更复杂。【参考方案2】:如果幼稚(我假设您的意思是线性)方法适用于 100 个条目(因此平均进行 50 次比较),那么二进制搜索对于 100,000 个条目将绰绰有余(最多需要 17 次比较)。
所以我根本不会为哈希而烦恼,而只是在启动时对字符串表进行排序(例如使用qsort
),然后使用二进制搜索(例如使用bsearch
)来查找条目。
【讨论】:
【参考方案3】:如果(最大)表大小已知,则带有链接的普通哈希表很容易实现。每个项目的大小开销只有两个整数。使用合理的哈希函数,每次查找平均只需要 1.5 次探测,这对于 100% 加载的表而言。
只有在您的数据没有变化的情况下,才能构建完美的散列。一旦它改变了,你就必须重新计算和重新散列,这比做一些额外的比较要贵得多。
【讨论】:
以上是关于哈希表查找 - 具有完美的哈希,在 C的主要内容,如果未能解决你的问题,请参考以下文章