我知道当人们不关心集合中元素的顺序时,人们会使用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
如何确定插入顺序?
很抱歉,如果之前有人询问,我已经在线搜索了一段时间,我找不到这个问题的具体答案。提前谢谢。
答案 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
上查看
通常通过应用%
运算符将值转换为适当的存储区索引。同样,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>
中的顺序是无序的。但是,假设使用了确定性散列并且完成了相同的插入操作顺序,程序的不同运行将使元素具有相同的顺序。以不同的顺序插入元素和/或使用为不同的运行生成不同值的哈希将产生不同的元素顺序。