哈希函数(通论)

时间:2010-11-04 18:52:06

标签: c# .net hash

我一直在寻找答案,我想知道是否有人知道如何在C#中明确地(从头开始)定义哈希函数。我知道有预定义的数据结构具有List功能,但我正在尝试理解这些对象的底层结构。

任何人都可以帮忙吗?例如,如果你有两个数组,你怎么能从这个数组创建一个哈希表?

2 个答案:

答案 0 :(得分:10)

关于hash tableshash functions的维基百科文章非常好听。您还可以查看Volume 3 of TAOCP。最后,在Reflector System.Collections.Hashtable看一眼可能是一种启发性体验。

如果您有更具体的问题,我们可能会提供更详细的见解。

答案 1 :(得分:2)

为了能够散列两个数组,它取决于数组所持有的数据类型。例如,如果你想要散列字符串数组,你需要额外的步骤来编码字符串和整数,然后进行散列,因为你需要的是将输入转换为哈希表的索引,给定一个哈希函数。当然,当您“转换输入”时,您必须解决密钥之间的冲突问题。换句话说,你必须尝试最小化散列到相同值的键的数量,这就是为什么数论(特别是使用素数)变得特别有用的原因。

我假设当你要求知道如何从两个数组'创建一个哈希表'时,你的意思是将两个数组中的数据作为表的键。在这种情况下,我不明白为什么你需要引用两个数组而不是一个包含两个数组的元素的更大的数组,除非你正在处理一个静态类型的编程语言,并且这两个数组可以有不同的类型。在这种情况下,您需要提出一个将元素转换为整数的方案。例如,如果要转换长度为n的字符串s,其中s [i]是字符串中的第i个字符(指其ASCII值)为整数,您可以查看 Java's hashCode() function does the job它本质上是如何计算的具有素数基的多项式,以避免将不同的字符串散列为相同的整数。除了它是素数之外,基数为31的原因是因为乘以31接近2的幂,所以31可以通过比特移位来有效地完成。

一旦你将所有元素都以整数的形式存在,你就能找到真正的问题。假设组合的组件彼此相对素数以便我们可以扩展到整个哈希表,那么我们可以从中进行精心组合的基本技巧。两种基本方法是分割方法乘法方法。这些方法本身,特别是除法方法,是不够的,因为有人可能最终确定散列键的函数。我会尝试解释构造散列函数的常用方法,但我可能不会像CLRS那样解释它们。另一方面,我可以给你一个满足的属性列表:

        
  • 你应该尽量减少碰撞
  •     
  • 您的函数应该能够将密钥哈希到任何插槽
  • (以免违反简单统一哈希)     
  • 您的功能应该很难逆向工程

请记住,为了满足最后一个属性,散列函数的某些组件通常至少应使它们映射键的插槽看起来是随机的。由于这种约束,我们仍然会有一个非零的碰撞概率,所以你要解决的下一个问题是碰撞解决