std :: set和std :: vector有什么区别?

时间:2011-12-31 06:24:42

标签: c++ stl

我正在学习STL。我读到了set容器。我想问你何时想使用set?阅读description of set之后看起来它没用,因为我们可以用vector代替它。你能说出vector vs set容器的优缺点吗?感谢

5 个答案:

答案 0 :(得分:91)

订购了set。根据您提供的仿函数,保证保持特定顺序。无论您添加或删除哪些元素(除非您添加了set中不允许的副本),它将始终被订购。

vector完全和您明确指定的顺序。 vector中的项目是您放置它们的位置。如果你把它们排除在外,那么它们就会失灵;你现在需要sort容器将它们按顺序放回来。

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

将项目插入vector所需的时间与vector中已有的项目数量成正比。将项目插入set所需的时间与项目数的 log 2 成正比。如果项目数量很大,那将是一个巨大的差异。 log 2(100,000)是~16;这是一个重大的速度提升。删除也是如此。

但是,如果您在初始化时一次完成所有插入操作,那么就没有问题了。您可以将所有内容插入vector,对其进行排序(支付该价格一次),然后对排序的vectors使用标准算法来查找元素并迭代排序列表。虽然对set元素的迭代不是很慢,但迭代vector的速度会更快。

因此,有些情况下排序vectorset更好。话虽这么说,除非你知道这是必要的,否则你真的不应该为这种优化付出代价。所以请使用set,除非您对所编写的系统类型有所了解(因此知道您需要这种性能)或者掌握分析数据,告诉您需要vector和不是set

答案 1 :(得分:9)

它们是不同的东西:你决定向量的排序方式,你也可以根据需要将尽可能多的相同的东西放入向量中。集合是根据该集合的内部规则排序的(您可以设置规则,但是集合将处理排序),并且您不能将多个相等的项目放入集合中。

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

总而言之,集合和向量具有不同的目的。你可以使用向量而不是集合,但它需要更多的工作,并且可能会严重损害性能。

答案 2 :(得分:5)

针对集合而不是向量搜索项目(O(log(n))vs O(n))。要针对向量搜索项目,您需要迭代向量中的所有项目,但是该集合使用红黑树来优化搜索,只会查找几个项目来查找匹配项。

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

但是矢量是无序的,你可以通过插入顺序来传播它。

答案 3 :(得分:5)

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

答案 4 :(得分:3)

表格cpluplus.com 设置:

  

集合是存储特定元素后面的唯一元素的容器   顺序。

所以集合是有序的,并且项目是唯一表示的

而vect:

  

向量是表示可以更改的数组的序列容器   大小

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

更喜欢设置:

  • 如果您希望过滤多个相同的值
  • 如果您希望按指定的顺序解析项目(在向量中执行此操作需要专门对向量进行排序)。

更喜欢矢量:

  • 如果你想保持相同的价值
  • 如果您希望以推送它们的顺序解析项目(假设您不处理矢量顺序)