我接受了Jim Balter 的回答,因为他是最接近我最终编码的那个人,但所有的答案都因为他们的帮助而得到了我的 +1。
这是我最终得到的算法。我编写了一个小的 Python 脚本,它生成 300 个 64 位整数,使得它们的二进制表示正好包含 32 个真位和 32 个假位。真实位的位置是随机分布的。
import itertools
import random
import sys
def random_combination(iterable, r):
"Random selection from itertools.combinations(iterable, r)"
pool = tuple(iterable)
n = len(pool)
indices = sorted(random.sample(xrange(n), r))
return tuple(pool[i] for i in indices)
mask_size = 64
mask_size_over_2 = mask_size/2
nmasks = 300
suffix='UL'
print 'HashType mask[' + str(nmasks) + '] = {'
for i in range(nmasks):
combo = random_combination(xrange(mask_size),mask_size_over_2)
mask = 0;
for j in combo:
mask |= (1<<j);
if(i<nmasks-1):
print '\t' + str(mask) + suffix + ','
else:
print '\t' + str(mask) + suffix + ' };'
脚本生成的C++数组使用如下:
typedef int_least64_t HashType;
const int maxTableSize = 300;
HashType mask[maxTableSize] = {
// generated array goes here
};
inline HashType xorrer(HashType const &l, HashType const &r) {
return l^mask[r];
}
HashType hashConfig(HashType *sequence, int n) {
return std::accumulate(sequence, sequence+n, (HashType)0, xorrer);
}
这个算法是迄今为止我尝试过的算法中最快的(this,this with cubes and this with a bitset of size 300)。对于我的“典型”整数序列,碰撞率小于 1E-7,这对于我的目的来说是完全可以接受的。