hash()%n 和 n%hash() 有什么区别

What is the difference between hash()%n and n%hash()

在许多书籍、教学大纲和教程中,我发现找到项目的合适单元格的一个好方法是计算单元格的编号:item.hash()%(n-1) = # of the bucket.

但是为什么会提到这个词呢?

倒数 (n-1)%item.hash() = # of the bucket 与它有何不同?

P.S。我知道 Java HashMap 使用 (n - 1) & hash,我只想了解这两种方法在稀疏键上的区别。

How does the inverse one (n-1)%item.hash() = # of the bucket differs from it?

基本不行

该表达式需要将散列码缩减为 0 .. n - 1 范围内的值,以便它可以用作大小为 n 的数组的下标。

但是 "inverse" 函数不会那样做。因此,如果您尝试使用它,(所谓的)存储桶下标会给出异常,因为 h % (n - 1) > (n - 1) 或 < 0 对于 Java 范围内的大多数 h 值=10=]类型。

正如@Zubuza 所指出的,余数 (%) 和除法 (/) 不可交换。

将运算符模数 % 视为一种通过 减少 将一组数字统一分布 的方法范围。这组数字实际上是输入键的哈希码。小范围是table.

的容量

当您想要在较小的 table 中分配索引以存储较大的数字时,这是一种有用的技术。

逆运算听起来很奇怪(而且没用):考虑到哈希码是高数且 n 很小,n % hash 将 return 总是 n,所以一点兴趣都没有。

Java 通过 hash & (length-1) 选择索引,事实上,这在算法上不等同于 hash % length,但它是一种替代方案 - 并且比模数 - 减少和分布的公式更便宜(感谢@Zabuza)。

hash % nn % hash 之间的区别在于 hash % n 将比 n % hash 分散得多。

n % hash 几乎总是等同于 n,因为 a % b 其中 b > a 等于 a(例如 15 % 30 = 15) .

I created a graph to show the differences(红色是 x % n,蓝色是 n % x,其中 x 代表散列)。

java 中的想法是避免“expensive%(mod)操作,而是进行相对便宜的 &(和) 手术。但这仅在 n 是 2 的幂时有效。因此,Java HashMap 始终使用 2 的幂作为桶数。