【问题标题】:What size bucket should I use for my hashtable?我应该为我的哈希表使用什么大小的桶?
【发布时间】:2014-05-17 08:05:33
【问题描述】:

我正在编写一个能够解决单词谜题的程序。本质上,我通过 Infile.txt 获取字典并用它创建一个哈希表。我将使用单独的链接,并将 java LinkedList 类用作哈希表的第二级(使用指向链接列表的简单数组)。随意提出一个更好的解决方案,因为我是一个新手数据结构。 读完字典后,我将根据来自 infile 的混乱字符串列表在哈希表中搜索单词。我现在不担心搜索。

字典大小为109530。那是输入数据的恒定大小。你会说哈希表的最佳大小是多少?我读过关于此的相互矛盾的东西,所以我想我会在这里问,所以请稍微解释一下你的推理。

最后,我将使用以下函数作为哈希函数:

Hash(string) = ( SumOf(AsciiValOfChar() * CharPosInString()) ) mod TableSize;

示例:字符串“abc”将为97(ascii value of 'a') * 1 + 98 * 2 + 99 * 3 mod tablesize。 因此,如果表大小为10,“abc”将为= 0 = 590 mod 0

对这个哈希函数有什么想法吗?

非常感谢大家,非常感谢您抽出宝贵的时间。

编辑:我没有使用 Java hastable / hashmap 类,而是我需要自己编写。这是一个练习。

【问题讨论】:

  • 你已经尝试过你的方法了吗?我的意思是,您是否创建了一个 HashTable 并用所有单词填充它?如果您想测试哈希函数的行为方式以及是否需要调整,那将是一件好事。
  • 在设计哈希表方案时有许多不同的考虑因素。但作为一般规则,假设您不为“同义词”使用辅助哈希,您希望将每个桶的“同义词”数量保持在最低限度(1 是理想的),同时不浪费空间桶。在某种程度上,这取决于您的散列算法的分布情况,也取决于您的溢出策略是什么,但对“最佳”表大小的一个很好的猜测是条目总数的一半。

标签: java hashtable


【解决方案1】:

tldr; 1) 使用 >= 109530 * 1.33 作为最终容量,2) 散列函数“将起作用”,即使不理想


桶数选择取决于使用的特定hash table implementation、数据和哈希函数质量。

由于有很多因素在起作用,我的建议是简单地编写哈希表,以便它可以根据需要重新增长/调整大小。只需提供配置选项来控制初始容量、填充因子 (0.75 is a good start) 和增长因子(加倍是一个好的开始)。然后可以在运行一些测试后对哈希表进行微调。

对桶大小使用 2 的幂会有效地导致余数运算“减少为掩蔽 [并且可以] 增加哈希函数不佳的问题”,这就是为什么有时建议不要这样做的原因。但是,关键字是“糟糕的哈希函数”,以及一些实现require a power of two and use an internal hash to mitigate this situation。由于这是一个简单的实现,只需选择一个足够数量级的奇数,例如二减一的幂。

就哈希函数本身而言,有几个目标,例如providing uniform distribution 和避免聚类。但是,建议的散列并不能很好地做到这一点,尤其是对于小的或类似的字符串。这样的哈希仍然可以工作 - 即使它比更好的对应物导致更多的冲突/聚类。

相反,请考虑 Java 的 String.hashCode,它使用了一个复合乘数,因为它应用于之前的哈希值。 (The .NET version is more complicated,但使用了类似的复合/运行哈希值的想法。)

for (int i = 0; i < value.length; i++) {
    h = 31 * h + val[i];
}

乘数 31 并不是唯一的“好”值,但它是 chosen carefully - 以避免退化的溢出特性,并且由于良好的裸机实现。

(对桶计数的模数不是散列函数的一部分。)

【讨论】:

    猜你喜欢
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多