根据高位(维持顺序)将哈希整数散列为大致相等大小的N个桶

时间:2012-12-18 17:55:23

标签: c++ algorithm data-structures

最好是快速方式。 N = 2^b案例非常简单。对于它,首先我要弄清楚我选择的类型中有多少位:

typedef unsigned int type;
size_t size = sizeof(type) * 8;

然后我将通过适当的位数执行右移以产生高b位的散列键。

type input = 0x657;
unsigned char b = 4;
unsigned char hash = input >> (size - b);

但如果我想要N = 3怎么办?或者2的任何其他非权力?假设我的N总是适合unsigned char(所以最多只有256个),那么散列一些input的最快方法是什么?虽然保持桶的范围不超过+/- 1,但也保留input的高位的顺序,就像上面的函数一样。

1 个答案:

答案 0 :(得分:3)

对于32位值,使用N进行64位乘法并保持前32位。 (类似地,对于其他大小,尽管如果你有64位值,乘法变得更加棘手。)

这是一个基本的证明大纲。

很明显,这种映射是保持秩序的;唯一的问题是每个桶中有多少值。现在,考虑一些存储桶j并找到映射到该存储桶的最小i。如果i落入存储区j,则表示Ni − j×232 = m位于0 ≤ m < 232,但如果i是最小的此类值0 ≤ m < N。 (否则,i−1也会落入专栏j。)

现在,定义w = ⌊232∕N⌋,这相当于说Nw − 232 = −m' where 0 ≤ m' < N。通过添加这两个公式,我们发现Ni + Nw - j×232 - 232 = m−m';简化,我们得到N(i+w)-(j+1)×232 = m−m'−N < m−m' < N。这意味着i + wi + w + 1是映射到j + 1的最小值(取决于m − m'是否为负数),这意味着有w映射到w + 1的1}}或j值。由于任何j都是如此,我们可以肯定地说只有两个存储桶大小,其中一个是⌊232∕N⌋。我在评论(现已删除)中做出的断言与其他可能的桶大小为⌈232∕N⌉的距离不远。

上述证据中232没有任何魔力;我可以使用任何值M。但这会使浓缩证据难以阅读。