使用除法方法进行散列意味着h(k)= k mod m。我读了那个
m不应该是2的幂。这是因为如果m = 2 ^ p,则h变为 只是k的最低位。通常我们选择m作为素数 数字不太接近2的幂。
有人可以用一个小例子解释最低位的部分吗?我认为所有(mod m)确实是它将结果包裹在范围m周围。如果m是2的幂,那么无论如何都无法看到问题。
答案 0 :(得分:4)
计算机中的所有数据都存储为二进制数据。二进制数写在base-2中。
如果您对数据进行哈希处理,则需要创建易于比较的指纹。如果我们有类似的数据与原始数据不完全相同,则不应创建相同的指纹(哈希)。
猜猜如果使用m m = 2^p (p is int >= 0)
,会发生什么。因为例如2 ^ 7是2 ^ 4的倍数,所以从2 ^ 4离开的所有位将减少为0.您切断了部分数据。这意味着如果二进制数的最左边的数据不同,它们将创建相同的散列。
示例:
k: 1111111111010101
m: 0000000001000000 (2^6)
k(m): 0000000000010101
现在为此做同样的事情:
k: 0000000000010101
m: 0000000001000000 (2^6)
k(m): 0000000000010101
嘿,这是相同的哈希!这正是为什么选择远离2 ^ p的数字的原因。这样,最左边的位做在计算散列时很重要,并且两个相似的数据块创建相同的散列的可能性要小得多。
答案 1 :(得分:0)
除数的余数可以通过重复删除除数直到要除数小于除数来计算。对于二进制数和两个除数的幂,此减法仅影响左侧的位,使其为0,但使右侧的位保持不变。
1110001111100001₂ 58337
- 0000000100000000₂ 2⁸
= 1110001011100001₂ 58081
___________________________
1110001011100001₂ 58081
- 0000000100000000₂ 2⁸
- 0000000100000000₂ 2⁸
...
= 0000000011100001₂ 57569
当除数不均匀时,反复删除除数时,所有低位会受到影响:
1110001111100001₂ 58337
- 0000000011000011₂ 195
= 1110001100011110₂ 58142
___________________________
1110001111100001₂ 58337
- 0000000011000011₂ 195
- 0000000011000011₂ 195
...
= 0000000000100000₂ 32
请注意,除数不能被2整除就足够了,因为每个2的因数会将二进制数向左移动一位数字,而减法只能在左边改变数字,而不能在右边改变数字。
除数与2的幂的距离越远,即数字等于0和1越多,则每次减法都会影响余数的位数。例如,这意味着模量78985(10011010010001001²)远远大于65537(10000000000000001²),即使它不是素数,而65537也不是。
这适用于散列为“差”的情况,即散列在所有输出位中的分布不均。如果我们有good hash,则可以使用所有哈希表大小,因此可以使用我们想要的除数,以及可以使用诸如fastrange之类的范围缩小方法。
*通常实际上并不是这样计算的,但是结果是等效的