哈希函数到无序容器的桶大小?

hash function to size of buckets for unordered containers?

为了将一个元素放入一个无序集合中,我们计算它的哈希值并将其放入相应的桶中。然而,我们的桶通常比散列函数的值范围少得多。 buckets和hash值的对应关系是怎么计算出来的?似乎使用了一些函数来反映 (0 ... size_t) -> (0 ... size_of_buckets - 1)。但是即使是好的散列函数,使用这样的函数也可能导致大量冲突。

许多哈希 table 被构建得足够通用以支持许多不同的哈希函数,因此它们中的大多数没有 "calculate" 哈希函数范围之间的对应关系和桶的数量。

然而,桶的数量取决于散列的内部结构 table(冲突解决技术等),尤其是这个称为 load factor 的值,并且当负载因子限制具有已达到的实现通常会按预定的常数因子增加桶的数量。

您应该更多地了解 std::unordered_map 界面并尝试使用以下功能以了解更多信息

http://en.cppreference.com/w/cpp/container/unordered_map/max_bucket_count http://en.cppreference.com/w/cpp/container/unordered_map/bucket_count http://en.cppreference.com/w/cpp/container/unordered_map/bucket_size http://en.cppreference.com/w/cpp/container/unordered_map/max_load_factor http://en.cppreference.com/w/cpp/container/unordered_map/load_factor

我不确定 std::unordered_map 标准中是否定义了确切的行为。然而,基本原则是这样的:始终保持桶数大于容器大小乘以一个小数(这个小数是 1.0/load_factor)。这样,碰撞应该很少见。

对于一个散列table,通常有两种计算方式bucket_index:

  1. 桶的数量选择为 2 的幂:计算哈希值,然后使用位操作提取它的一些 lower/higher 位。此方法需要一个 "good" 哈希函数,其中每一位都是随机的
  2. 桶数选择质数:计算hash,然后modulo运算,计算bucket_index。此方法不需要 "too good" 哈希函数

对于方法1.,如果哈希函数质量不好,你会得到很多冲突。对于方法 2.,即使使用质量不太好的哈希函数,通常也很少发生冲突。但是,方法 1. 通常更快,因为位运算比 mod 快得多(但有一些技术可以使它成为 faster),并且质量足够好的哈希函数通常很便宜。