unordered_set如何确定c ++中的插入顺序?

use*_*071 3 c++ unordered-set

我知道人们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;}
Run Code Online (Sandbox Code Playgroud)

它给我

This is the test string...
Abcdef
Hello world
Run Code Online (Sandbox Code Playgroud)

而且我尝试将其运行3或4次,它仍然给我相同的输出,这意味着有一种方法unordered_set可以确定插入顺序。

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

抱歉,如果之前曾有人问过我,我已经在网上搜索了一段时间,但找不到该问题的具体答案。提前致谢。

Whi*_*TiM 5

没有特定的顺序...它使用默认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...");
Run Code Online (Sandbox Code Playgroud)

对于特定的STL实现,它可以解决:

Hello maps to: 14420674105493498572
abcd maps to: 10830572898531769673
test maps to: 13068738153895491918
Run Code Online (Sandbox Code Playgroud)

C ++ Shell上实时查看

通常通过应用%运算符将值转换为适当的存储区索引。同样,std::unordered_set'迭代器'没有被要求依次遍历所有存储桶(冲突是什么?)。因此,您不应该依赖程序运行之间从迭代器观察到的任何顺序。


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

散列函数仅需要在程序的一次执行中为相同的输入产生相同的结果即可;这允许使用盐腌的哈希来防止冲突DoS攻击。