Unordered_set如何确定C 中的插入顺序

How does unordered_set determine the inserting order in c++?

本文关键字:插入 顺序 何确定 set Unordered      更新时间:2023-10-16

我知道人们不在乎集合中元素的顺序时使用unordered_set。但是,当我在C shell上运行示例程序

#include <iostream>
#include <unordered_set>
#include <string>
int main()
{
std::unordered_set<std::string> inputSet;
inputSet.insert("Hello world");
inputSet.insert("Abcdef");
inputSet.insert("This is the test string...");
for(const auto &val : inputSet)
  std::cout << val.c_str() << std::endl;
return 0;}

它给了我

This is the test string...
Abcdef
Hello world

我试图将其运行3或4次,它仍然给我提供相同的输出,这意味着unordered_set确定插入顺序。

有人可以解释unordered_set如何确定插入顺序?

对不起,如果以前问过,我已经在线搜索了一段时间,我找不到这个问题的特定答案。预先感谢。

没有特定的排序...它使用默认的 std::hash来哈希字符串。无论哈希值是什么,它都会转换为容器中的适当存储桶索引。

我们正在谈论的哈希值可以得到:

auto hello = std::hash<std::string>()("Hello world");
auto abcd = std::hash<std::string>()("Abcdef");
auto test = std::hash<std::string>()("This is the test string...");

对于特定的STL实现,这将解决:

Hello maps to: 14420674105493498572
abcd maps to: 10830572898531769673
test maps to: 13068738153895491918

看到它活在C 外壳上

通常通过应用%操作员将值转换为适当的存储桶索引。同样,std::unordered_set的迭代器并未要求依次迭代所有存储桶(碰撞呢?)。因此,您不应依靠从程序运行之间的迭代器观察到的任何订购。


从C 14中,std::hash<>明确允许在不同程序运行之间产生不同的结果。引用:

哈希功能仅需要为 在一个程序的单个执行中相同的输入;这允许腌制 阻止碰撞DOS攻击的哈希。

如下所述

在内部,这些元素不是按任何特定顺序排序的,而是 组织成水桶。将元素放入哪个水桶的依赖 完全取决于其价值。这允许快速访问 单个元素,由于一旦计算了哈希,它就指的是 确切的水桶将元件放入。

因此,它要么使用默认的用户或提供的哈希算法将其排序为哈希桶。

std::unordered_set<T>中的顺序是无序的。但是,假设使用确定性哈希并完成了相同的插入操作顺序,则程序的不同运行将以相同的顺序具有元素。以不同的顺序插入元素和/或使用Hash为不同的运行产生不同值的哈希将产生不同的元素顺序。