我现在正在学习STL。我读了有关set
容器的内容。当你想使用set
时有什么问题吗?阅读set的描述后,它看起来毫无用处,因为我们可以用vector
代替它。您能说出vector
与set
容器的优缺点吗?谢谢。
set
是有序的。根据你提供的函数对象,它保证始终保持在特定顺序中。无论添加或删除什么元素(除非你添加了重复项,在set
中不允许),它总是有序的。vector
只有你明确给出的顺序。在vector
中的项目就在你放置它们的位置。如果你按照顺序放置它们,那么它们就是有序的;否则,你现在需要对容器进行排序,以使它们重新排列。set
的使用相对有限。通过适当的约束,可以将项插入到vector
中并保持其有序。但是,如果你不断地向容器中添加和移除项,则vector
将遇到许多问题。它将执行许多元素的复制/移动等操作,因为它实际上只是一个数组。vector
中插入一项所需的时间与vector
中已经存在的项的数量成正比。向set
中插入一项所需的时间与项数的log₂成正比。如果项数很大,则这是一个巨大的速度改进。log₂(100,000)约为16;这是一个重大的速度改进。移除也是如此。vector
,对其进行排序(支付那个价格一次),然后使用排序vectors
的标准算法来查找元素并迭代排序列表。虽然遍历set
中的元素不是特别慢,但遍历vector
更快。有些情况下,经过排序的vector
会比set
更快。尽管如此,除非你知道这种优化是必要的,否则你真的不应该费心去做。所以,除非你对你正在编写的系统有经验(从而知道你需要这种性能),或者手头有分析数据告诉你需要使用vector
而不是set
,否则请使用set
。
set
是否被排序只是一种实现细节,从数学角度来讲,集合本身没有顺序。 - Paul Mantastd::set
并不是由数学定义的,它是由 C++ 规范定义的。规范指定它是有序的。 - Nicol Bolasset
,那么顺序显然对你很重要。保持std::vector
排序需要大量的努力。你基本上必须围绕容器构建一个类型。所以我不建议这样做,除非你知道有合法的性能提升。当然,如果你有访问flat_set
的权限,那么几乎没有理由使用常规的set
。 - Nicol Bolasset
是无序的,但C++中的std::set
则是有序的。 - liberforceset.emplace(it)
似乎要好得多,而不是 if (vec.find(it) != vec.end() ) { vec.emplace(it) }
(对于 erase
更是如此!) - underscore_d表单 cpluplus.com 中的set:
set是一种容器,它按照特定顺序存储唯一元素。
因此,set是有序的并且项目具有唯一性。
而vect:
向量是表示可以改变大小的数组的序列容器。
因此,vector按您填充它的顺序,并且可以容纳多个相同的项。
推荐使用set:
推荐使用vector:
简单的区别是set只能包含唯一的值,并且它是有序的。因此,你可以将其用于需要在每次插入/删除后连续排序值的情况。
set<int> a;
vector<int> b;
for (int i = 0; i < 10; ++i)
{
int val = rand() % 10;
a.insert(val);
b.push_back(val);
}
cout << "--SET---\n"; for (auto i : a) cout << i << ","; cout << endl;
cout << "--VEC---\n"; for (auto j : b) cout << j << ","; cout << endl;
--SET---
0,1,2,4,7,8,9,
--VEC---
1,7,4,0,9,4,8,8,2,4,
对比向量(O(n))和集合(O(log(n))),在集合中搜索项目更快。使用向量搜索项目需要迭代向量中的所有项目,但是集合使用红黑树来优化搜索,只需查找少量项目即可找到匹配项。
集合是有序的,这意味着您只能按顺序从最小的开始迭代它,或者按相反的顺序。
但是向量是无序的,您可以按插入顺序遍历它。