Part.I Attention
使用set
需要注意的地方:
- 加引用
#include <set>
- 和
map
、multimap
容器不同,使用set
容器存储的各个键值对,要求键key
和值value
必须相等。 - 关联式容器
set
(集合)中元素具有唯一性,系统会根据元素的值自动对其进行排序。 - C++ STL中标准关联容器
set, multiset, map, multimap
内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为 RB 树(Red-Black Tree)。
Part.II Function
Chap.I set 头文件中的函数
set 中常用的函数如下图所示
下面列了一个表格,说明了这些函数的含义。
函数 | 含义 |
---|---|
begin() |
返回指向容器中第一个(注意,是已排好序的第一个)元素的双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
end() |
返回指向容器最后一个元素(注意,是已排好序的最后一个)所在位置后一个位置的双向迭代器,通常和 begin() 结合使用。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
rbegin() |
返回指向最后一个(注意,是已排好序的最后一个)元素的反向双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
rend() |
返回指向第一个(注意,是已排好序的第一个)元素所在位置前一个位置的反向双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
cbegin() |
和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。 |
cend() |
和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。 |
crbegin() |
和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。 |
crend() |
和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。 |
find(val) |
在 set 容器中查找值为 val 的元素,如果成功找到,则返回指向该元素的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
lower_bound(val) |
返回一个指向当前 set 容器中第一个大于或等于 val 的元素的双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
upper_bound(val) |
返回一个指向当前 set 容器中第一个大于 val 的元素的迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
equal_range(val) |
该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的值为 val 的元素(set 容器中各个元素是唯一的,因此该范围最多包含一个元素)。 |
empty() |
若容器为空,则返回 true;否则 false。 |
size() |
返回当前 set 容器中存有元素的个数。 |
max_size() |
返回 set 容器所能容纳元素的最大个数,不同的操作系统,其返回值亦不相同。 |
insert() |
向 set 容器中插入元素。 |
erase() |
删除 set 容器中存储的元素。 |
swap() |
交换 2 个 set 容器中存储的所有元素。这意味着,操作的 2 个 set 容器的类型必须相同。 |
clear() |
清空 set 容器中所有的元素,即令 set 容器的 size() 为 0。 |
emplace() |
在当前 set 容器中的指定位置直接构造新元素。其效果和 insert() 一样,但效率更高。 |
emplace_hint() |
在本质上和 emplace() 在 set 容器中构造新元素的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示新元素生成位置的迭代器,并作为该方法的第一个参数。 |
count(val) |
在当前 set 容器中,查找值为 val 的元素的个数,并返回。注意,由于 set 容器中各元素的值是唯一的,因此该函数的返回值最大为 1。 |
Chap.II algorithm 中的函数
在头文件#include <algorithm>
中,有有关集合的操作如:求交集、并集、差集等。
set_intersection
:取集合交集set_union
:取集合并集set_difference
:取集合差集set_symmetric_difference
:取集合对称差集
这几个函数的用法差不多,都是5个参数,前面4个参数含义都是一样的,第5个参数有两种,以set_union()
为例:
set_union(A.begin(),A.end(),B.begin(),B.end(),inserter(C1 , C1.begin()));
set_union(A.begin(),A.end(),B.begin(),B.end(),ostream_iterator(cout," “));
前面四个参数前两个参数是集合A
的begin()
和end()
;第3,4个参数是集合B
的begin()
和end()
;第一种用法的含义是将求并集的结果存到集合C1
里面,第二种用法的含义是将求并集的结果输出。
另外关于set
和vector
相互转换可以进行如下操作:
vector<int> v;
v = {
1,2,2,3,3,4}; //建立vector
set<int> st(v.begin(), v.end()); //在构造函数中可以直接实现vector转set
v.assign(st.begin(), st.end()); //用assign实现set转vector
Part.III Code
LeetCode 中题目 2032. 至少在两个数组中出现的值 很适合用set
来做,下面是C++
的解法:
class Solution {
public:
vector<int> twoOutOfThree(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3) {
set<int> s1(nums1.begin(),nums1.end()), s2(nums2.begin(),nums2.end()), s3(nums3.begin(),nums3.end()), s12,s13,s23;
set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s12, s12.begin() ));
set_intersection(s1.begin(),s1.end(),s3.begin(),s3.end(),inserter(s12, s12.end() ));
set_intersection(s2.begin(),s2.end(),s3.begin(),s3.end(),inserter(s12, s12.end() ));
vector<int> ans;
ans.assign(s12.begin(), s12.end());
return ans;
}
};