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

时间:2016-12-26 18:26:36

标签: c++ unordered-set

我知道当人们不关心集合中元素的顺序时,人们会使用unordered_set。但是,当我在in the WikiBook on JavaPersistence

上运行示例程序时
#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如何确定插入顺序?

很抱歉,如果之前有人询问,我已经在线搜索了一段时间,我找不到这个问题的具体答案。提前谢谢。

3 个答案:

答案 0 :(得分:4)

没有特定的排序......它使用默认的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++Shell

上查看

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

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

  

哈希函数只需要产生相同的结果   一次执行程序中的相同输入;这允许盐渍   哈希可以防止DoS攻击。

答案 1 :(得分:1)

如此处所述http://en.cppreference.com/w/cpp/container/unordered_set

  

在内部,元素不按任何特定顺序排序,但是   组织成水桶。元素放入哪个桶取决于   完全取决于其价值的哈希值。这允许快速访问   单个元素,因为一旦计算了哈希,它就会引用   该元素被放入的确切桶。

因此,它使用默认或用户提供的哈希算法来排序哈希桶。

答案 2 :(得分:0)

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