存储大型随机数的最佳哈希函数是什么?

时间:2013-03-17 05:42:44

标签: c algorithm data-structures

我想在数据结构中存储大数字,为此,我想使用哈希函数,以便插入,删除或搜索可以很快。但我无法决定应该使用哪种哈希函数?

总的来说,我想知道如何确定哈希函数对任何特定问题都有好处?

编辑:我认为让人们对使用术语“随机”感到困惑。这里有随机,我的意思是,我没有任何特定范围的数字,我必须选择[任何32位整数],但我有总数没有将被给予存储在数据结构,如5000个数字。所以建议我为这个场景最好的哈希函数以及为什么你认为它是最好的?

3 个答案:

答案 0 :(得分:4)

如果数字是均匀随机的,只需使用选择低位的散列函数。

unsigned hash_number(long long x)
{
    return (unsigned) x;
}

答案 1 :(得分:1)

即使您的输入数字是完全随机的,使用h(x)= x仍可能会造成性能问题。假设您的数字是从0,2,4,...,2k随机选择的图像,虽然是随机的,但是假设两个桶大小的功率,它们都不会映射到哈希表(桶0)的第一个桶。因此,真正重要的是输入数字的信息熵。

在你的情况下,一个很好的选择是Thomas Wang的整数散列函数,它是可逆的并且保持良好的雪崩效应(http://en.wikipedia.org/wiki/Avalanche_effect)。有一篇文章描述了Thomas Wang的哈希函数及其反函数:http://naml.us/blog/2012/03

答案 2 :(得分:0)

你的问题对我没有意义。使用散列算法存储一些随机数是过度的。如果问题还有其他问题,那么数据结构的选择将取决于更多的东西(你没有说的)。

如果这些数字确实是随机的或伪随机的,那么您只需要一个堆栈或循环缓冲区 - 将新的随机数添加(推送)到数据结构中的功能以及从中删除(弹出)现有随机数的功能结构。如果要按顺序检索它们,请使用循环缓冲区。散列函数在各个方面都比用于保存随机数列表的简单堆栈(或循环缓冲区)更糟糕 - 它更复杂,运行速度更慢,并且使用更多内存。

大多数语言/环境都提供可以使用(或提供为)“词典”类的哈希函数,这些函数可以提供效率指导。通常,您可以通过分配更多内存来加快字典类的速度 - 当哈希键发生冲突时,它们会变慢。因此,所有可能数字中实际数字的“密度”很重要。

因此,如果您必须保留100个这样的数字,则可以使用仅查看最后12位的哈希函数。这给出了2 ^ 12 = 4096个可能的哈希值,因此冲突将仅发生在100/2048的时间,小于5%。另一方面,你使用的内存超过你应该的20倍。 (此函数与将数字的模数取为2 ^ 12的基数相同,与Epp建议的相似。)

基于正确处理哈希冲突的哈希函数编写存储类(必要时),优雅地处理重复数据,如果你查看坏数据(就像每个数字一样)都不会发狂,而且效率很高,这不是一项微不足道的任务。

另一方面,实现堆栈或循环缓冲区非常简单,非常有效,并且具有完全可预测的行为。

你确定你没有把它变得比它需要的更复杂吗?