我有这个困扰我的特殊代码,
// 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来重新哈希。
答案 0 :(得分:1)
有三种可能性:
1)原作者或多或少地随机构建了散列函数,看到它们运行得很好,并将其留在那里。
2)原作者的测试数据很好地代表了实际数据,并发现这些功能对他的确切应用非常有效。
3)此代码执行得非常糟糕,并且他的哈希表根本没有高效运行。
唯一真正的要求是输出看起来均匀分布在哈希表上,无论他实际遇到什么输入,并且总是为同一输入产生相同的输出。虽然这些功能通常表现不佳,但它们可能足以满足这一特定应用。
顺便说一句,这种类型的开放哈希在删除时不起作用。例如,假设您向表中添加一条记录。然后你去添加第二个,但它与第一个碰撞,所以你跳过前面添加第二个。一切都很好 - 你可以找到第一个记录(直接)和第二个记录(当你在第二个记录的哈希位置找到它时跳过第一个记录)。
但如果删除第一条记录,你如何找到第二条记录呢?当您查看第二个记录的哈希位置时,您什么都找不到。你试试跳过吗?如果是这样,多少次?
这些问题有解决方法,但它们往往很容易做错。