无冲突的哈希函数

Hash Function without collision

本文关键字:函数 哈希 冲突      更新时间:2023-10-16

基本上我使用的是rabin karp中使用的哈希函数。

与滚动哈希的快速实现中的函数相同,但我不是哈希字符串,而是哈希整数向量。

const unsigned PRIME_BASE = 257;
const unsigned PRIME_MOD = 1000000007;
unsigned hash(const std::vector< unsigned int >& Line)
{
unsigned long long ret = 0;
for (int i = 0; i < Line.size(); i++)
{
ret = ret*PRIME_BASE + Line[i];
ret %= PRIME_MOD;
}
return ret;
}

问题是我遇到了很多碰撞。更改质数可以最小化或最大化碰撞,但我无法避免它。

任何想法 如何避免与此类功能或更好的功能发生冲突 ?

你没有。

哈希的全部意义在于从大域获取输入,并在较小的域中生成输出。

就这一进程的本质而言,碰撞是不可避免的。

对于某些特定类别的数据集,您可以尝试降低它们的可能性,但您已经探索过这样做。

您可以做得更好一点(减少碰撞的机会(以添加更多的哈希函数。例如: 创建 2 个哈希函数,具有不同的 PRIME BASE 和 PRIME MOD,以及存储长长的一对。

另一个问题可能是如果 Line 存储了许多零,所以最好向值添加一些随机(初始化后固定的(偏移。 例如,对于 Robin-Karb,如果您想计算"A"和"AA"哈希,最好添加移位值,否则这两个字符串哈希值都将为 0。(我的意思是,如果您转换以下字符:f(char c({return c-'A';}

另一个有趣的话题我认为,如果你选择一个好的哈希函数(从随机方面(,并且你的输入也是随机的,那么当行向量中不同项目的数量小于sqrt(哈希函数的范围(时,就不会发生列,这就是生日悖论。您当前的范围是 1e9+7,因此其 sqrt 约为 3e4。如果您使用 2 哈希函数,则组合范围是其范围的乘法。