我正在使用double哈希方法为整数实现哈希类。输入将是随机整数,可以是正数也可以是负数。
我的问题是如何计算负整数的哈希值?
这是方法:
hash function 1 h: h(k) = k mod (p)
hash function 2 s(k)= p –2 – (k mod(p-2))
p = table size, k = key
计算h(k)后,如果没有碰撞,它将被插入其位置。如果有碰撞,我将计算(h(k)+ s(k))mod p并将密钥存储在计算的结果值中。
所以我的问题是如果键是负整数,我应该在散列之前取其绝对值(使其为正)吗?或者还有其他方法吗?
答案 0 :(得分:2)
来自Princeton Algorithms website:
问:使用(s.hashCode()%M)或Math.abs(s.hashCode())%M散列到0到M-1之间的值有什么问题?
答:%运算符如果第一个参数为负,则返回一个非正整数,这将创建一个数组索引越界错误。令人惊讶的是,绝对值函数甚至可以返回负整数。如果其参数为Integer.MIN_VALUE,则会发生这种情况,因为无法使用32位二进制补码整数表示得到的正整数。这种错误很难被追踪,因为它只会发生在40亿次中! [" polygenelubricants"的字符串哈希码是-2 ^ 31。 ]
Java根据哈希码as follows计算索引:
static int indexFor(int hashcode, int length) {
return hashcode & (length-1);
}
答案 1 :(得分:0)
假设您首先使用功能1进行哈希,然后将结果放在功能2中,结果将始终为正数。
在功能2中
If k > 0 => 0 < (k mod (p - 2)) < p - 2
因此,函数2返回正值
If k < 0 => (k mod (p - 2)) < 0
然后-(k mod (p - 2)) > 0
因此,函数2返回正值
在任何一种情况下,无论输入是正还是负,双重散列都会从函数2返回正值。