哈希键乘以9和模数

时间:2012-05-29 08:35:26

标签: c# math hash

我有这个困扰我的特殊代码,

   // exbPtr points to 128-bit unsigned integer
   // lgID is a "short" with 0xFFFF being the max value

   int hash = (*exbPtr + (int)lgID * 9) & tlpLengthMask;

最初这个“哈希表”,实际上是一个数组,初始化为256个元素,tlpLengthMask设置为255。

然后就是这个神秘的代码......上面有一条评论说“如果我们到达这里......就会发生碰撞”。然后它再次开始循环,所以看起来这是一个哈希冲突,并重新散列?

   hash = (hash + (int)lgID * 2 + 1) & tlpLengthMask;

此外,还有大量的调试代码表明这个数组的长度应该是2的幂,因为我们使用掩码作为模数。

有人可以解释一下作者的意图吗?这背后的原因是什么?

编辑 - 我想要辨别的是为什么他乘以9,然后再乘以2来重新哈希。

1 个答案:

答案 0 :(得分:1)

有三种可能性:

1)原作者或多或少地随机构建了散列函数,看到它们运行得很好,并将其留在那里。

2)原作者的测试数据很好地代表了实际数据,并发现这些功能对他的确切应用非常有效。

3)此代码执行得非常糟糕,并且他的哈希表根本没有高效运行。

唯一真正的要求是输出看起来均匀分布在哈希表上,无论他实际遇到什么输入,并且总是为同一输入产生相同的输出。虽然这些功能通常表现不佳,但它们可能足以满足这一特定应用。

顺便说一句,这种类型的开放哈希在删除时不起作用。例如,假设您向表中添加一条记录。然后你去添加第二个,但它与第一​​个碰撞,所以你跳过前面添加第二个。一切都很好 - 你可以找到第一个记录(直接)和第二个记录(当你在第二个记录的哈希位置找到它时跳过第一个记录)。

但如果删除第一条记录,你如何找到第二条记录呢?当您查看第二个记录的哈希位置时,您什么都找不到。你试试跳过吗?如果是这样,多少次?

这些问题有解决方法,但它们往往很容易做错。