0

我正在使用双散列方法实现整数的散列类。输入将是随机整数,可以是正数或负数。

我的问题是如何计算负整数的哈希值?

这是方法:

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 并将密钥存储在计算的结果值中。

所以我的问题是,如果键是负整数,我应该在散列之前取它的绝对值(使其为正)吗?或者还有其他方法吗?

4

2 回答 2

2

来自普林斯顿算法网站

问:使用 (s.hashCode() % M) 或 Math.abs(s.hashCode()) % M 散列到 0 到 M-1 之间的值有什么问题?

答:如果 % 运算符的第一个参数为负数,则返回一个非正整数,这会产生数组索引越界错误。令人惊讶的是,绝对值函数甚至可以返回一个负整数。如果它的参数是 Integer.MIN_VALUE 就会发生这种情况,因为生成的正整数不能用 32 位二进制补码整数表示。这种错误很难追踪,因为它只会在 40 亿分之一中出现![“polygenelubricants”的字符串哈希码是-2^31。]

Java 从哈希码计算索引如下

 static int indexFor(int hashcode, int length) {
     return hashcode & (length-1);
 }
于 2015-05-03T19:29:20.423 回答
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 返回正值。

于 2015-05-03T19:26:58.113 回答