Std: : set 和 std: : Vector 之间的区别是什么?

我现在正在学习 STL。我看过 set集装箱的报道。我有一个问题,你什么时候想使用 set?在阅读 集合的描述集合的描述之后,它看起来是没有用的,因为我们可以用 vector代替它。你能说一下 vectorset容器的优缺点吗。谢谢

100437 次浏览

它们是不同的东西: 你决定向量是如何排序的,你也可以把许多相等的东西放入一个向量,因为你喜欢。集合按照集合的内部规则排序(您可以设置规则,但集合将处理排序) ,并且您不能将多个相等的项放入集合中。

当然,您可以维护一个惟一项的向量,但是当您执行面向集合的操作时,您的性能会受到很大影响。例如,假设您有一组10000个项目和一个由10000个不同的无序项目组成的向量。现在假设您需要检查一个值 X 是否在集合中的值之中(或者在向量中的值之中)。当 X 不在其中时,搜索向量的速度会慢100倍左右。在计算集合联合和交叉点时,您会看到类似的性能差异。

总之,集合和向量有不同的用途。您可以使用向量而不是集合,但是这将需要更多的工作,并且可能会严重影响性能。

比起向量(O (log (n)) vs O (n)) ,在集合中搜索条目要快得多。要根据向量搜索一个条目,您需要迭代向量中的所有条目,但是集合使用红黑树来优化搜索,只有少数条目会查找匹配。

该集合是有序的,这意味着您只能按顺序从最小的一个迭代到最大的一个,或者逆序。

但是向量是无序的,你可以通过插入顺序来遍历它。

已经订购了 set。根据您提供的函数,保持特定的顺序是 保证。无论添加或删除什么元素(除非添加重复的元素,这在 set中是不允许的) ,它始终是有序的。

vector具有您明确给出的顺序,而 只有具有您明确给出的顺序。vector中的项目是您放置它们的位置。如果您将它们按顺序排列,那么它们就是按顺序排列的; 现在需要 sort容器来将它们按顺序排列。

不可否认,set的使用相对有限。有了适当的纪律,一个可以插入项目到一个 vector和保持秩序。但是,如果您不断地从容器中插入和删除项,那么 vector将会遇到许多问题。它将执行大量的元素复制/移动等操作,因为它实际上只是一个数组。

将一个项目插入 vector所需的时间与 vector中已有的项目数成正比。将一个项目插入 set所需的时间与项目数量的 日志2成正比。如果项目的数量很大,这是一个巨大的差异。Log2(100,000)是 ~ 16; 这是一个重大的速度改进。移除也是一样。

但是,如果在初始化时同时执行所有插入,那么就没有问题。您可以将所有内容插入到 vector中,对它进行排序(只需支付一次这个代价) ,然后使用排序后的 vectors的标准算法来查找元素,并在排序后的列表中进行迭代。虽然在 set元素上的迭代并不慢,但是在 vector上的迭代更快。

因此,在某些情况下,排序后的 vector优于 set。也就是说,除非你知道这是必要的,否则你真的不应该为这种优化的花费而烦恼。因此,除非您有编写系统的经验(因此知道您需要这种性能) ,或者手头有分析数据告诉您需要的是 vector而不是 set,否则请使用 set

表格: http://www.cplusplus.com/rel = “ norefrer”> cpluplus.com 设定:

集合是在特定的 秩序。

因此集合是有序的,而且项目是唯一表示的

而 vect:

向量是序列容器,表示可以在 尺寸。

所以矢量是按照你填充它的顺序,并且可以容纳多个相同的项目

首选集:

  • 如果您希望筛选多个相同的值
  • 如果您希望按照指定的顺序解析项目(在向量中这样做需要对向量进行特定的排序)。

偏好矢量:

  • 如果你想保持相同的值
  • 如果您希望按照按下的顺序解析项(假设您不处理向量顺序)

简单的区别是 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,