独特的哈希函数,没有任何冲突

时间:2016-10-26 04:07:01

标签: c hash hashtable

所以给我一个格式为XYYYYZ的键,其中X是来自'A'的字符 - 'Z',YYYY是和0从0到9999,而Z是来自'A' - '的字符C'。我想在没有任何冲突的情况下制作一个独特的哈希函数。

有人告诉我,有人制作的最小桌子是780,000,但我不知道怎么做。

我能想到的是X-'A'从0到26得到一个数字然后乘以100,000再乘以YYYY乘以10然后加上(Z - 'A')

因此Z1025A为2,610,250,L4444C为1,144,443

并且可能的组合是2699993和/ 2,700,000将具有大约29%的使用率。

但还有其他方法可以减少表的大小吗?

2 个答案:

答案 0 :(得分:1)

只是做

std::vector<char>

答案 1 :(得分:1)

此格式的键的最小可能哈希表大小为780000,因为有26种方法可以选择第一个字符,10种方法可以选择接下来的四种,以及3种方法来选择最终字符。也就是说,有26 * 10 * 10 * 10 * 10 * 3 = 780000个可能的键。要查找哈希函数,请将哈希键视为计数器。重新排列这样的元素:

  

ZXYYYY

从0处的所有元素开始,每个'Y'元素在达到9后翻转。'X'在达到25后翻转,'Z'在达到2后翻转。因此,我们可以为四个'Y'元素:

  

y4 y3 y2 y1 - &gt; y1 +(y2 * 10)+(y3 * 100)+(y4 * 1000)

这部分钥匙只是一个基础10计数器。剩下的一对元素组成一个基数为26的计数器,你可以通过将0到25之间的数字分配给第一个值('X'),将数字从0到25分配到第二个,为这一对分配一个数字,并添加结果:

  

z x - &gt; x +(z * 26)

对于y4 y3 y2 y1,我们将得到0到9999之间的值,对于z x,我们将得到0到675之间的值。如果我们将此值乘以10000,我们可以添加获得的值使y4 y3 y2 y1获取密钥的唯一值。也就是说,四个低阶位置从0到9为1,0到90为几十,0到900为几百,0到9000(以千为单位),而两个高阶位置可以视为从0到6750000的计数成千上万。这为此哈希函数提供了可能的6760000个唯一键。但由于您的特定情况将'z'限制为三个字符,因此z x只有3 * 26 = 78种可能性,因此使用此方法可获得780000个唯一哈希值,然后可以编写哈希函数:

  

hval = y1 +(y2 * 10)+(y3 * 100)+(y4 * 1000)+(x + z * 26)* 10000

其中y1,y2,y3,y4,x和z都表示整数值。或者,使用C char s:

int y1, y2, y3, y4;
char x, z;
long hval;

hval = y1 + (y2 * 10) + (y3 * 100) + (y4 * 1000) + ((x - 'A') + (z - 'A') * 26) * 10000;

我应该补充一点,以这种方式将拉丁字母的字符转换为整数不能保证按标准工作,但只要你有ASCII或UTF-8字符集就可以工作。