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

ash*_*him 65 c++ stl

我现在正在学习STL.我读到了set容器.我有问题什么时候想用set?在阅读了集合的描述后,看起来它没用,因为我们可以替代它vector.你能说vectorvs set容器的优点和成本吗?谢谢

Nic*_*las 95

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

A vector完全且只有您明确给出的顺序.a vector中的项目是你放置它们的地方.如果你把它们排除在外,那么它们就会失灵; 你现在需要把sort容器按顺序放回去.

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

将项目插入a所需的时间vector与已经存在的项目数量成正比vector.将物品插入a所需的时间与物品数量set的log 2成比例.如果项目数量很大,那将是一个巨大的差异.log 2(100,000)是~16; 这是一个重大的速度提升.移除也是如此.

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

因此,有些情况下排序vector打败了set.话虽这么说,除非你知道这是必要的,否则你真的不应该为这种优化付出代价.因此,set除非您对所编写的系统有所了解(因此知道您需要该性能),或者手头的分析数据告诉您需要a vector而不是a,否则请使用a set.

  • @PaulManta:`std :: set`不是由数学定义的; 它由C++规范定义.规范声明它是有序的. (40认同)
  • 但是,"set"不仅仅是一个实现细节吗?从数学角度讲,一组没有订单. (5认同)
  • Python用户的一个陷阱:Python`set`是无序的,但是C++`std :: set`是有序的. (3认同)
  • "所以使用一套,除非......"嗯..可能更好地使用Stroupstrup的建议:"而且,是的,我的推荐是默认使用std :: vector.更一般地说,除非有充分的理由,否则使用连续的表示不要." (2认同)

das*_*ght 10

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

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

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

  • +1唯一性.我无法相信没有其他人不愿指出这一点.耻辱!独特性是主要的好处.而不是贬值,但即使随之而来的`erase` /`emplace`.often的容易导致我使用`[unordered_] set`,即使它理论上可能更慢 - 尽管通常在速度为no的设置部分担心,我只担心以后几乎无法阅读代码!例如,我想确保一个物品放在容器中,但只能放一次; 编写`set.emplace(it)`比编写`if(vec.find(it)!= vec.end()){vec.emplace(it)}`(以及更多的`erase`更好! ) (3认同)

jo_*_*jo_ 8

表单cluplus.com 集:

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

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

而向量:

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

所以向量按照你填写的顺序,并且可以容纳多个相同的项目

喜欢套装:

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

更喜欢向量:

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


Sri*_*ali 6

简单的区别是 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;
Run Code Online (Sandbox Code Playgroud)

输出是

--SET---
0,1,2,4,7,8,9,
--VEC---
1,7,4,0,9,4,8,8,2,4,
Run Code Online (Sandbox Code Playgroud)


Zan*_*Jie 5

搜索项目的集合比向量(O(log(n))vs O(n))更快.要针对向量搜索项目,您需要迭代向量中的所有项目,但是该集合使用红黑树来优化搜索,只有少数项目将被查找以找到匹配项.

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

但是矢量是无序的,您可以通过插入顺序来移动它.

  • 但二进制搜索仅在向量排序时才有效. (27认同)