【发布时间】:2016-02-14 09:00:40
【问题描述】:
我正在尝试设置一个哈希表(在 C++ 中,使用 unordered_map 容器),其中包含 1875 个整数项目,这些项目随机分布在 0 到 4891 的区间内。现在我的问题是这个区间内的分布是不是统一的,而是看起来像这样:
其中 1875 个随机整数中的每一个都被绘制为一个点,其中 x 对应于整数值,y = 1(以便可视化分布)。
显然,分布是这样的,即在没有随机整数的地方存在很大的差距。如果我使用恒等函数作为我的散列函数(即使用随机整数本身作为散列值),我得到 714 个空桶、814 个带有单个元素的桶、499 个带有 2 个元素的桶和 21 个带有 3 个或更多元素的桶。
我使用的是英特尔 C++ 编译器,它使用 2 的幂来计算哈希表中的桶数。就我而言,现在哈希表有 2^11 = 2048 个桶。
对于这种情况,什么是好的散列函数?我的理解是,在这种情况下,一个好的哈希函数会摆脱这些聚集的整数,并以更均匀的分布将它们打乱,但是如何实现呢?
【问题讨论】:
-
所以你只有 1800 个整数?对 1800 个键值对的排序
std::vector然后进行二进制搜索怎么样?这至少值得衡量。 -
Boost 的
flat_map(overview) (API docs) 是@BaummitAugen 建议的一个很好的完整实现——它的接口就像一个unordered_map,但它的实现就像一个有序向量。 -
@user3208430,我来了——各种关联容器的here's a benchmark,与用于随机搜索的 flat_map 相比,unordered_map 做得非常好(尽管 flat_map 用于迭代)。跨度>
-
存储桶负载的分布实际上优于任何标准哈希函数。一个选项可以是无符号乘以一个(大)奇数。
-
有4891个桶,用恒等函数作为哈希函数怎么样。它可能会占用更少的空间,因为您不需要指针和溢出链以及所有这些东西。 (它被称为索引)并且 30% 的负载因子并不是那么奇怪,如果它保证你完美 hashing ...