我正在编写一个能够解决单词难题的程序。基本上我通过Infile.txt接收字典并用它创建一个Hash表。我将使用单独的链接,并将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类,而是我需要编写自己的类。这是一个练习。答案 0 :(得分: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。由于这是一个简单的实现,只需选择一个足够大的奇数,例如2到-1的幂。
就哈希函数本身而言,有几个目标,如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的乘数不是唯一的&#34;好的&#34;值,但它是chosen carefully - 以避免退化溢出特性,并且由于良好的裸机实现。
(对于桶数的模数不是散列函数的一部分。)