对于SLT库中的关联式容器,我们第一个学到的容器就是map,它属于有序关联式容器且只允许唯一键值存在,如果大家不熟悉map可跳转《初识模板类pair》学习map容器;当允许重复键值存在时,我们就学习了multimap。今天我们开始学习set容器,set可以被视为是特殊的map,它要求键必须等于值。所以,插入时只需要放入一个元素即可,可见“键值对”的概念被隐式转换了。set最大的特点是能够自动去重和排序,其底层是红黑树实现,时间复杂度为O(log n),相比动态更新的排序去重容器(“先插入数据,后排序,最后去重”)效率更高。
接下来我们将通过代码的方式学习如何创建一个set容器:
#include<bits/stdc++.h>//万能头,以效率为中心 #include<string> #include<set>//包含头文件,养成好习惯 /*set*/ /*动态排序去重*/ using namespace std; /*set的创建方式*/ void test() { set<int> s1;//直接创建 set<int> s2{5,4,3,2,1} ;//初始化列表 set<int> s3(s2) ;//拷贝构造 set<int> s4; s4=s2;//'='运算符重载 set<int> s5(s2.begin(),s2.end()) ;//迭代器范围构造 } int main(){ test(); return 0; }
代码成功编译,set容器成功创建。
接下来让我们看看set容器里都有哪些成员函数:
函数名 | 参数 | 功能描述 |
---|---|---|
insert | (const T& value) | 插入单个元素 |
emplace | (Args&&... args) | 原地构造插入元素 |
erase | (const T& key) | 删除指定键的元素 |
erase | (iterator pos) | 删除指定位置的元素 |
clear | 无参数 | 清空所有元素 |
find | (const T& key) | 查找元素,返回迭代器 |
count | (const T& key) | 统计元素个数(0或1) |
contains | (const T& key) | 检查是否包含元素(C++20) |
lower_bound | (const T& key) | 返回第一个≥key的迭代器 |
upper_bound | (const T& key) | 返回第一个>key的迭代器 |
equal_range | (const T& key) | 返回相等元素的范围 |
empty | 无参数 | 检查set是否为空 |
size | 返回元素个数 | |
begin | 返回起始迭代器 | |
end | 返回结束迭代器 | |
swap | (set& other) | 交换两个set的内容 |
set容器的成员函数实际上与map容器大差不差,相比map容器而言,我们这里只需要记住set容器主要通过insert()和emplace()来添加元素,而且set容器没有at()来访问元素。(emplace效率高于insert)
那我们就创建一个set容器然后简单地调用一些成员函数:
#include<bits/stdc++.h>//万能头,以效率为中心 #include<string> #include<set>//包含头文件,养成好习惯 /*初识set*/ /*动态排序去重*/ using namespace std; /*调用set成员函数*/ void test() { set<int> s;//升序排列 s.emplace(1) ;//emplace比insert高效 s.emplace(25) ; s.emplace(10) ; s.emplace(0); /*通过迭代器遍历set容器*/ cout << "通过迭代器遍历set容器: "; for(set<int>::iterator it = s.begin();it!=s.end();++it) cout << *it << " "; cout << '\n'; cout << "set容器里面总共有【" << s.size() << "】个元素\n"; s.clear();//清除set容器 } int main(){ test(); return 0; }
代码编译结果如下:
代码成功编译!
总结:不能因为set是单个元素插入就简单认为它是序列式容器,set本质是有序关联式容器,同时set能够实现动态去重和排序,与map相比没有at()函数,也没有重载'[]'运算符,主要是通过emplace()或insert()插入元素,多个插入只能使用insert()。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程