我正在学习STL。我读了关于set
容器的文章。我有什么疑问要使用set
?阅读set的描述后,它似乎没有用,因为我们可以用代替它vector
。您能否说说vector
vsset
容器的优缺点。谢谢
我正在学习STL。我读了关于set
容器的文章。我有什么疑问要使用set
?阅读set的描述后,它似乎没有用,因为我们可以用代替它vector
。您能否说说vector
vsset
容器的优缺点。谢谢
Answers:
Aset
被订购。这是保证留在一个特定的顺序,根据算符您提供。无论您添加或删除什么元素(除非您添加重复项,都不允许在其中进行重复set
),它始终是有序的。
Avector
具有并且只有您显式给出的顺序。中的项目vector
是您放置它们的地方。如果您将它们乱序放置,则说明它们乱七八糟。您现在需要sort
将容器放回原处。
诚然,set
具有相对有限的用途。只要遵守适当的纪律,就可以将物品插入vector
并保持有序。但是,如果您不停地从容器中插入和取出物品,vector
将会遇到很多问题。因为它实际上只是一个数组,所以它将进行很多元素的复制/移动等等。
将项目插入中所需的时间vector
与中已存在的项目数成正比vector
。将项目插入到a中set
所花费的时间与log2成正比与项目数。如果项目数量很大,那就有很大的不同。log 2(100,000)为〜16;这是一个重大的速度改进。删除也一样。
但是,如果您在初始化时一次完成所有插入操作,则没有问题。您可以将所有内容插入vector
,对其进行排序(一次支付该价格),然后使用标准算法进行排序vectors
以查找元素并遍历排序后的列表。尽管对a的元素进行迭代set
并不是完全缓慢,但是对a进行迭代vector
却更快。
因此,在某些情况下,排序vector
优于set
。话虽如此,除非您知道这样做是必要的,否则您真的不应该为这种优化而费心。因此,set
除非您对正在编写的系统类型有经验(因此知道您需要这种性能)或手头有可能需要avector
而不是a的分析数据,否则请使用a set
。
set
订购不仅是实施细节吗?从数学上讲,集合没有顺序。
std::set
不是由数学定义的;它是由C ++规范定义的。并且规范指出它是有序的。
set
,那么订单对您显然很重要。保持std::vector
排序需要大量的精力。基本上,您必须围绕容器构建一个类型。因此,除非您知道要获得合理的性能提升,否则我不建议您这样做。当然,如果您可以访问flat_set
,则可以,几乎没有理由使用normal set
。
set
是无序的,但是C ++std::set
是有序的。
它们是不同的东西:您决定向量的排序方式,也可以根据需要将尽可能多的相等的东西放入向量中。集合是根据该集合的内部规则排序的(可以设置规则,但是集合将处理排序),并且不能将多个相等的项放入集合中。
当然,您可以维护一组唯一的项目,但是当您进行面向集合的操作时,您的性能会受到很大影响。例如,假定您有一组10000个项目和一个10000个不同无序项目的向量。现在假设您需要检查值X是否在集合中的值之中(或向量中的值之中)。如果X不在项目中,则搜索向量的速度将慢100倍。在计算集合并集和交集时,您会看到类似的性能差异。
总而言之,集合和向量具有不同的目的。您可以使用向量而不是集合,但是这将需要更多的工作,并且可能会严重损害性能。
erase
/伴随的轻松性也emplace
常常使我使用[unordered_]set
,即使它在理论上可能比较慢-尽管通常在不关心速度的设置部分中,我只担心几乎不能稍后阅读代码!例如,我想确保将物品放入容器中,但只能放入一次;它似乎远更好写的set.emplace(it)
比if (vec.find(it) != vec.end() ) { vec.emplace(it) }
(多仍然erase
!)
形式cpluplus.com 设置为:
集合是按照特定顺序存储唯一元素的容器。
因此该集合是有序的,并且项是唯一表示的
而vect:
向量是表示可以改变大小的数组的序列容器。
所以向量按您填充的顺序排列,可以容纳多个相同的项目
首选设置:
首选矢量:
与向量相比(O(log(n))vs O(n)),针对集合搜索项目的速度更快。要针对向量搜索项目,您需要迭代向量中的所有项目,但是集合使用红黑树来优化搜索,将只寻找几个项目来查找匹配项。
该集合是有序的,这意味着您只能按顺序或相反的顺序将其从最小的一个迭代到最大的一个。
但是向量是无序的,您可以按插入顺序对其进行移动。
std::binary_search
一个std::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,