使用另一个哈希函数处理冲突?

时间:2013-12-03 03:23:36

标签: java string hash collision

我的问题不是关于双重散列技术http://en.wikipedia.org/wiki/Double_hashing,这是一种解决冲突的方法。它是关于处理字符串哈希表中的现有冲突。比如说,我们有一个碰撞:同一个桶中有几个字符串,所以现在我们必须检查字符串。计算快速字符串比较的另一个哈希函数似乎是有意义的(比较哈希值以便快速拒绝)。哈希键可以延迟计算并与字符串一起保存。你用这种技术了吗?你能提供参考吗?如果没有,你认为这是不值得做的,因为性能提升是值得怀疑的吗?一些说明:

  1. 因为我在Java中进行了测量,所以我添加了标签“Java”:String.hashCode()在大多数情况下优于String.equals()(并且BTW大大优于手动哈希码计算:hashCode = 31 * hashCode + strInTable.charAt( ⅰ));
  2. 当然,可以询问任何字符串比较,不一定是哈希表中的字符串。但我正在考虑具有大量字符串的特定情况,这些字符串保存在哈希表中。
  3. 如果桶中的字符串有些相似(如Rabin-Karp算法),这可能是有意义的。在一般情况下寻找你的意见。

2 个答案:

答案 0 :(得分:2)

许多基于哈希的集合存储集合中每个项目的哈希值,前提是每个项目的哈希值都会在添加到集合时计算,而代码则在哈希值中查找项目集合必须知道它的散列,比较散列值将是一种降低虚假命中成本的快捷方法。例如,如果一个包含16个桶的哈希表,其中包含四个每个1,000个字符的字符串,并且将搜索许多1,000个字符的字符串,这些字符串与除最后几个字符之外的所有表项都匹配,更多超过6%的搜索将包含一个包含近匹配字符串的存储桶,但是一个小得多的部分将击中一个存储桶,该存储桶包含一个32位hashCode与正在搜索的字符串相匹配的字符串。由于几乎相同的字符串的比较是昂贵的,因此比较完整的32位哈希码是有帮助的。

如果有一个大型不可变集合可能需要存储在哈希表中并与其他此类集合进行匹配,那么使这些集合计算和缓存更长的哈希函数并使用equals方法可能会有一些价值。在继续进行之前比较那些较长哈希函数的结果。在这种情况下,计算较长的散列函数通常几乎与计算较短的散列函数一样快。此外,不仅对较长哈希码的比较大大降低了误报将导致不必要的“深度”比较的风险,而且计算更长的哈希函数并将它们组合到报告的hashCode()中可以大大减少强烈的危险 - 相关的哈希冲突。

答案 1 :(得分:0)

只有比较(查找)的数量与条目数相比较时才比较哈希才有意义。你需要一个大的哈希值(32位是不够的;你想要至少128位),这将是昂贵的计算。您可能希望分摊将大量探测器上的每个字符串散列到存储桶中的成本。

至于它是否值得,它依赖于高度依赖性。找出答案的唯一方法是实际使用您的数据并比较两种方法的性能。