C ++ 0x即将推出unordered_set
,该版本可在boost
其他许多地方使用。我了解的是unordered_set
具有O(1)
查找复杂性的哈希表。另一方面,set
只有一棵具有log(n)
查询复杂性的树。为什么在地球上有人会set
代替使用unordered_set
?即是否有需要set
?
C ++ 0x即将推出unordered_set
,该版本可在boost
其他许多地方使用。我了解的是unordered_set
具有O(1)
查找复杂性的哈希表。另一方面,set
只有一棵具有log(n)
查询复杂性的树。为什么在地球上有人会set
代替使用unordered_set
?即是否有需要set
?
Answers:
对于想要迭代集合项的人而言,顺序很重要。
< >
?
无序集合必须通过以下几种方式来支付其O(1)平均访问时间:
set
比存储相同数量的元素使用更少的内存unordered_set
。set
可能比a中的查找更快unordered_set
。unordered_set
,他们经常保证有更好的最坏情况复杂的set
(例如insert
)。set
种种元素,如果你想将它们按顺序访问是有益的。set
s的<
,<=
,>
和>=
。unordered_set
不需要支持这些操作。<
)。
每当您喜欢树而不是哈希表时。
例如,在最坏的情况下,哈希表为“ O(n)”。O(1)是平均情况。树木在最坏的情况下是“ O(log n)”。
在以下情况下使用设置:
在以下情况下使用unordered_set:
例子:
组:
输入:1,8,2,5,3,9
输出:1,2,3,5,8,9
无序设置:
输入:1,8,2,5,3,9
输出:9 3 1 8 2 5(可能是此顺序,受哈希函数影响)
主要区别:
注意:(在某些情况下set
更方便)例如vector
用作key
set<vector<int>> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl; // I have override << for vector
// 1 2
// 1 3
之所以vector<int>
可以作为关键,set
是因为vector
覆盖operator<
。
但是,如果使用unordered_set<vector<int>>
,则必须为创建一个哈希函数vector<int>
,因为vector没有哈希函数,因此必须定义一个像这样的哈希函数:
struct VectorHash {
size_t operator()(const std::vector<int>& v) const {
std::hash<int> hasher;
size_t seed = 0;
for (int i : v) {
seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
};
vector<vector<int>> two(){
//unordered_set<vector<int>> s; // error vector<int> doesn't have hash function
unordered_set<vector<int>, VectorHash> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl;
// 1 2
// 1 3
}
你可以看到在某些情况下 unordered_set
更为复杂。
主要引用自:https : //www.geeksforgeeks.org/set-vs-unordered_set-c-stl/ https://stackoverflow.com/a/29855973/6329006
因为std :: set是标准C ++的一部分,而unordered_set不是。C ++ 0x不是标准,Boost也不是。对于我们许多人来说,可移植性是必不可少的,这意味着必须遵守标准。
考虑扫掠线算法。这些算法在散列表中将完全失败,但是在平衡树中可以很好地工作。为了给您一个扫掠线算法的具体示例,请考虑财富算法。http://en.wikipedia.org/wiki/Fortune%27s_algorithm
g++
6.4 stdlibc ++有序与无序设置基准
我对这个主要的Linux C ++实现进行了基准测试,以了解两者之间的区别:
有关完整的基准测试细节和分析的信息,请参见:用C ++设置的STL的底层数据结构是什么?我在这里不再重复。
“ BST”表示“经过测试,std::set
而散列图”表示“经过测试” std::unordered_set
。std::priority_queue
我在其中分析了“堆” :堆与二进制搜索树(BST)
快速总结:
该图清楚地表明,在这种情况下,当项目超过100k时,散列图的插入总是快得多,并且随着项目数的增加,差异会增大
这种速度提升的代价是您无法高效地顺序移动。
曲线清楚地表明排序std::set
是基于BST的并且std::unordered_set
是基于哈希图的。在参考答案中,我进一步确认了通过GDB一步调试代码。
map
vs的类似问题unordered_map
:在使用琐碎的键的情况下,使用map而不是unordered_map有什么优势吗?
临时而言,如果您希望将其转换为其他格式,则可以方便地将它们联系起来。
还有可能的是,虽然访问速度更快,但是建立索引或在创建和/或访问索引时使用的内存的时间会更长。