在许多书籍,课程提纲和教程中,我已经看到找到一个项目的正确单元格的一个不错的选择是计算单元格的数量:item.hash()%(n-1) = # of the bucket.
但是为什么要提到这个特定的表达呢?
倒数(n-1)%item.hash() = # of the bucket
与它有何不同?
P.S。我知道Java HashMap使用(n - 1) & hash
,我只想了解这两种方法在稀疏密钥方面的区别。
答案 0 :(得分:2)
存储桶的倒数(n-1)%item.hash()=#与它有何不同?
基本上不起作用。
该表达式需要将哈希码减少为0 .. n-1范围内的值,以便可以将其用作大小为n的数组的下标。
但是“反向”功能无法做到这一点。因此,如果您尝试使用它,则(指定的)存储桶下标会给出异常,因为对于Java WebRequest request = WebRequest.Create(url);
request.CookieContainer = new CookieContainer();
范围内的大多数h值,h%(n-1)>(n-1)或<0类型。
@Zubuza指出余数(%)和除法(/)不可交换。
答案 1 :(得分:2)
考虑算子模量%
是通过在较小范围内减少来均匀分布一组数字的一种方式。实际上,这组数字是输入键的哈希码。较小的范围是表格的容量。
当您要在较小的表中分配索引以存储较大的数字时,这是一种有用的技术。
倒数操作听起来很奇怪(也没用):考虑到哈希码是高数字且n小,n % hash
总是返回n
,所以一点都不感兴趣
Java实际上是通过hash & (length-1)
选择索引的,这在算术上不等同于hash % length
,但是它是减少和分发(比@Zabuza少)的一种替代方法,并且比模数公式便宜。
答案 2 :(得分:1)
hash % n
与n % hash
之间的区别在于hash % n
的分布要比n % hash
多得多。
n % hash
几乎总是等同于n
,因为a % b
其中b > a
等于a
(例如15 % 30 = 15
)。 / p>
I created a graph to show the differences(红色为x % n
,蓝色为n % x
,其中x
代表哈希)。
java中的想法是避免执行'expensive'%
(mod)操作,而执行相对便宜的&
(and)操作。但这仅在n
为2的幂时有效。因此,Java HashMap的存储桶数始终使用2的幂。