C++ STL 之集合 set 详解

Part.I Attention

在这里插入图片描述

使用set需要注意的地方:

  • 加引用#include <set>
  • mapmultimap 容器不同,使用 set 容器存储的各个键值对,要求键 key 和值 value 必须相等。
  • 关联式容器set(集合)中元素具有唯一性,系统会根据元素的值自动对其进行排序。
  • C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为 RB 树(Red-Black Tree)。

官网:https://cplusplus.com/reference/set/

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.firstlower_bound() 方法的返回值等价,pair.secondupper_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," “));

前面四个参数前两个参数是集合Abegin()end();第3,4个参数是集合Bbegin()end();第一种用法的含义是将求并集的结果存到集合C1里面,第二种用法的含义是将求并集的结果输出。


另外关于setvector相互转换可以进行如下操作:

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;
    }
};

猜你喜欢

转载自blog.csdn.net/Gou_Hailong/article/details/128398866