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 种种元素,如果你想将它们按顺序访问是有益的。sets的<,<=,>和>=。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一步调试代码。
mapvs的类似问题unordered_map:在使用琐碎的键的情况下,使用map而不是unordered_map有什么优势吗?
临时而言,如果您希望将其转换为其他格式,则可以方便地将它们联系起来。
还有可能的是,虽然访问速度更快,但是建立索引或在创建和/或访问索引时使用的内存的时间会更长。