Hash 函数
我正在尝试散列这些值Hash 函数,hash,hashtable,perfect-hash,Hash,Hashtable,Perfect Hash,我正在尝试散列这些值 10, 100, 32, 45, 58, 126, 3, 29, 200, 400, 0 我需要一个函数,将它们映射到一个大小为13的数组,而不会引起任何冲突 我花了好几个小时仔细考虑这个问题,在谷歌上搜索,但我还是弄不明白。我还没有找到可行的解决办法 我怎样才能找到这种散列函数呢?我玩过gperf,但我不太懂它,也无法得到我想要的结果。如果你知道确切的键,那么生成一个完美的哈希函数就很简单了- int hash (int n) { switch (n) {
10, 100, 32, 45, 58, 126, 3, 29, 200, 400, 0
我需要一个函数,将它们映射到一个大小为13的数组,而不会引起任何冲突
我花了好几个小时仔细考虑这个问题,在谷歌上搜索,但我还是弄不明白。我还没有找到可行的解决办法
我怎样才能找到这种散列函数呢?我玩过gperf,但我不太懂它,也无法得到我想要的结果。如果你知道确切的键,那么生成一个完美的哈希函数就很简单了-
int hash (int n) {
switch (n) {
case 10: return 0;
case 100: return 1;
case 32: return 2;
// ...
default: return -1;
}
}
找到一个
我尝试了一些方法,发现其中一种是半手动的:
(n ^ 28) % 13
半手动部分是以下ruby脚本,我使用该脚本使用一系列参数测试候选函数:
t = [10, 100, 32, 45, 58, 126, 3, 29, 200, 400, 0]
(1..200).each do |i|
t2 = t.map { |e| (e ^ i) % 13 }
puts i if t2.uniq.length == t.length
end
我做了一个快速检查,使用SHA256散列函数,然后在Mathematica中进行13的模除运算。对于C++,这个函数应该在OpenSSL库中。看这个
如果你做了大量的散列和查找,模块化除法是一个非常昂贵的重复操作。还有另一种将n位哈希函数映射到i位索引的方法。请参阅Michael Mitzenmacher的这篇文章,了解如何在C中使用位移位操作。希望这会有所帮助。Bob Jenkins也有一个这样的程序:
除非你非常幸运,否则对于给定的数据集没有“好”的完美哈希函数。完美的散列算法通常在键上使用一个简单的散列函数(使用足够的位以避免冲突),然后使用一个表来完成它。只是一些准分析性的散列: 在你的一组数字中,总共11个,3个是奇数,8个是偶数。 查看最简单的散列形式-%13-将为您提供以下散列值: 10 - 3, 100 - 9, 32 - 6, 45 - 6, 58 - 6, 126 - 9, 3 - 3, 29 - 3, 200 - 5, 400 - 10, 0-0 当然,由于碰撞的数量,这是不可用的。需要更详细的东西 为什么说这是显而易见的? 考虑到数字太少,任何精心设计的——或者更确切地说,“不那么简单”——算法都可能比switch语句或(我更喜欢)简单地搜索大小为11个位置的无符号短/长向量并使用匹配的索引慢 为什么要使用向量搜索
%13
。但是低阶位的和
运算成本较低,相当于二次幂的模
我尝试编写一个简单的程序(用Python)来搜索11个数据点的完美散列,使用诸如((x shift_值)之类的简单形式
def find_hash():
def hashf(val,i,j=None,k=None):
返回(右移(val,i)^右移(val,j)^右移(val,k))&0xF
对于X范围内的i(-7,8):
对于x范围内的j(i,8):
#对于x范围内的k(j,8):
#j=无
k=无
输出=设置()
对于数据中的val:
hash_val=hashf(val,i,j,k)
如果哈希值>=13:
通过
#中断
如果输出中存在哈希值:
打破
其他:
输出。添加(哈希值)
其他:
打印i、j、k、输出
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
find_hash()
尝试以下方法,将n值映射到0到12之间的唯一索引
(1369%(n+1))% 13 < /p>对不起,我把它编辑成C++,然后C++标签从问题中删除。如果你想,你可以回复。ME,它应该是C类伪代码,现在更好了,Tythe是一个有效的表搜索。哈希函数的好处之一是:它允许比表搜索更快地评估命中/误。@克雷格明显比表格搜索快,即使使用
gcc-O0
这也比我的机器上的简单线性表格搜索快5倍,使用-O2
线性搜索需要一秒钟,time
报告100万次查找的总时间0.00
,速度几乎与公认的答案相同使用-O0
的迭代次数超过1亿次,使用-O2
的迭代次数在0.2s以内。如果您只需要计算出密钥是否存在/有效-哈希(n),则此哈希函数会更快==-1
不需要内存访问…您可以安全地添加键,同时函数保持完美。您的哈希可能比数据表查找更快,但这不是我的意思。澄清一下:您的哈希可能适用于这个小数据集,同意。B
#define HASH(x) ((((x) << 2) ^ ((x) >> 2)) & 0xF)
data = [ 10, 100, 32, 45, 58, 126, 3, 29, 200, 400, 0 ]
def shift_right(value, shift_value):
"""Shift right that allows for negative values, which shift left
(Python shift operator doesn't allow negative shift values)"""
if shift_value == None:
return 0
if shift_value < 0:
return value << (-shift_value)
else:
return value >> shift_value
def find_hash():
def hashf(val, i, j = None, k = None):
return (shift_right(val, i) ^ shift_right(val, j) ^ shift_right(val, k)) & 0xF
for i in xrange(-7, 8):
for j in xrange(i, 8):
#for k in xrange(j, 8):
#j = None
k = None
outputs = set()
for val in data:
hash_val = hashf(val, i, j, k)
if hash_val >= 13:
pass
#break
if hash_val in outputs:
break
else:
outputs.add(hash_val)
else:
print i, j, k, outputs
if __name__ == '__main__':
find_hash()