我正在尝试编写一个生成Pearson完美哈希的生成器。请注意,我不需要最小的完美哈希。维基百科说,使用随机算法(其中S是密钥集)可以在O(| S |)时间内找到Pearson完美哈希。但是,我还没能在网上找到这样的算法。这甚至可能吗?
注意:我不想使用gperf / cmph / etc。我宁愿编写自己的实现。
答案 0 :(得分:1)
Pearson的original paper概述了构造排列表 T 的算法,以实现完美的散列:
有时可以修改这个新哈希函数核心的表 T ,以便在适度的单词列表上产生最小的,完美的哈希函数。实际上,通常可以为特定单词选择函数的确切值。例如,Knuth [3]用一种算法来说明完美的散列,该算法将31个常用英语单词的列表映射到-10到30之间的唯一整数。表II中的表 T 映射了这些相同的31个单词按字母顺序从1到31的整数。
虽然表II中构建表格的过程过于复杂,但未在此处详述,以下重点将使感兴趣的读者重复此过程:
- 表 T 是通过整数的伪随机置换(0 ... 255)构建的。
- 逐个地,将所需的值分配给列表中的单词。通过交换表中的两个元素来实现每项任务。
- 对于每个单词,考虑进行交换的第一个候选人是 T [ h [ n - 1]⊕ C [ n ]],计算该单词的哈希函数时引用的最后一个表元素。
- 如果在先前分配的单词的散列期间引用了表格元素,或者在同一单词的散列中引用了它,则无法交换该表格元素。
- 如果规则4禁止必要的交换,则注意力转移到先前引用的表元素 T [h [ n - 2]⊕ C [ n - 1]]。
醇>该程序并不总是成功。例如,使用ASCII字符代码,如果单词“a”哈希为0而单词“i”哈希值为15,则表明单词“in”必须哈希为0.初始尝试将Knuth的31个单词映射到由于这个原因,整数(0 ... 30)失败了。转移到范围(1 ... 31)是解决这个问题的临时策略。
这会篡改 T 是否会破坏散列函数的统计行为?不认真。当26,662个字典条目被分成256个区间时,得到的分布仍然与均匀分布没有显着差异(χ2= 266.03,255 d.f., p = 0.30)。散列128个随机选择的字典单词导致平均27.5次碰撞,而未修改的 T 平均为26.8次。当如上所述扩展此函数以产生16位哈希索引时,相同的测试产生相当多的冲突(4,870对比4,721与未修改的 T ),尽管分布仍然不显着不同于均匀(χ²= 565.2,532 df, p = 0.154)。