【C++】STL标准模板库容器set

🦄个人主页:修修修也

🎏所属专栏:C++

⚙️操作环境:Visual Studio 2022


目录

📌关联式容器set(集合)简介

📌set(集合)的使用

🎏set(集合)的模板参数列表

🎏set(集合)的构造函数

🎏set(集合)的迭代器

🎏set(集合)的容量

🎏set(集合)的修改操作

📌关联式容器multiset简介 

📌关联式容器multiset使用

结语


        在之前对STL的学习中,我们已经接触过STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,根据"数据在容器中的排列"特性,这些容器统称为序列式(sequence)容器,因为其底层为线性序列的数据结构,里面存储的是元素本身

        还有一种容器是关联式(associative)容器, 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高

        下图列出了STL中的各种容器,以及其基层与衍生层的关系:


📌关联式容器set(集合)简介

        我们先来看一下cplusplus.com - The C++ Resources Network网站对set的文档介绍:

        总结一下:

  1. set是按照一定次序存储元素的容器。
  2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
  5. set在底层是用二叉搜索树(红黑树)实现的。

        注意:

  • 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放value,但在底层实际存放的是由<value, value>构成的键值对。
  • set中插入元素时,只需要插入value即可,不需要构造键值对。
  • set中的元素不可以重复(因此可以使用set进行去重)。
  • 使用set的迭代器遍历set中的元素,可以得到有序序列。
  • set中的元素默认按照小于来比较。
  • set中查找某个元素,时间复杂度为:$log_2 n$
  • set中的元素不允许修改(因为修改key可能会导致二叉搜索树结构被破坏)。
  • set中的底层使用二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))来实现。

📌set(集合)的使用

🎏set(集合)的模板参数列表

        set的模板参数及含义如下:


🎏set(集合)的构造函数

        set的构造函数及其功能如下:

        使用示例如下:

#include<iostream>
#include<vector>
#include<set>
using namespace std;int main()
{//构造一个没有元素的空容器set<int> s1;for (auto e : s1){cout << e << " ";}cout << endl;vector<int> v;v.push_back(2);v.push_back(5);v.push_back(1);v.push_back(4);v.push_back(3);//迭代器区间构造set<int> s2(v.begin(), v.end());for (auto e : s2){cout << e << " ";}cout << endl;//拷贝构造set<int> s3(s2);for (auto e : s3){cout << e << " ";}cout << endl;return 0;
}

        运行效果如下:


🎏set(集合)的迭代器

        set的迭代器相关函数及其功能如下:

        使用示例如下:

int main()
{vector<int> v;v.push_back(2);v.push_back(5);v.push_back(1);v.push_back(4);v.push_back(3);//迭代器区间构造set<int> s(v.begin(), v.end());//正向迭代器set<int>::iterator it_b = s.begin();	//访问正向迭代器开始cout << *it_b << endl;set<int>::iterator it_e = s.end();		//访问正向迭代器结束--it_e;									cout << *it_e << endl;++it_e;while (it_b != it_e){cout << *it_b << " ";			//使用正向迭代器遍历set++it_b;}cout << endl;//反向迭代器set<int>::reverse_iterator rit_b = s.rbegin();		//访问反向迭代器开始cout << *rit_b << endl;set<int>::reverse_iterator rit_e = s.rend();		//访问反向迭代器结束--rit_e;cout << *rit_e << endl;++rit_e;while (rit_b != rit_e){cout << *rit_b << " ";			//使用反向迭代器遍历set++rit_b;}cout << endl;return 0;
}

        运行结果如下:


🎏set(集合)的容量

        set的容量相关函数及其功能如下:

        使用示例如下:

int main()
{//构造一个没有元素的空容器set<int> s1;cout << s1.empty() << endl;cout << s1.size() << endl;cout << s1.max_size() << endl;vector<int> v;v.push_back(2);v.push_back(5);v.push_back(1);v.push_back(4);v.push_back(3);//迭代器区间构造set<int> s2(v.begin(), v.end());cout << s2.empty() << endl;cout << s2.size() << endl;cout << s2.max_size() << endl;return 0;
}

        运行结果如下:


🎏set(集合)的修改操作

        set的修改相关函数及其功能如下:

函数声明功能介绍
pair<iterator, bool> insert(const value_type&x)在set中插入元素x,实际插入的是<x, x>构成的
键值对,如果插入成功,返回<该元素在set中的
位置,true>,如果插入失败,说明x在set中已经
存在,返回<x在set中的位置,false>
void erase ( iterator position )

删除set中position位置上的元素

size_type erase ( const key_type& x )删除set中值为x的元素,返回删除的元素的个数
void erase ( iterator first, iterator last )删除set中[first, last)区间中的元素
void swap ( set<Key,Compare,Allocator>& st )交换两个set中的元素
void clear ( )将set中的元素清空
iterator find ( const key_type& x ) const返回set中值为x的元素的位置
size_type count ( const key_type& x ) const返回set中值为x的元素的个数

        insert,erase,clear,find函数使用示例如下:

int main()
{//构造一个没有元素的空容器set<int> s1;//插入元素s1.insert(3);s1.insert(1);s1.insert(7);s1.insert(4);s1.insert(0);s1.insert(8);s1.insert(2);s1.insert(6);s1.insert(9);s1.insert(5);for (auto k : s1){cout << k << " ";}cout << endl;set<int>::iterator pos = s1.find(1);//迭代器删除元素s1.erase(pos);for (auto k : s1){cout << k << " ";}cout << endl;//key值删除元素s1.erase(3);for (auto k : s1){cout << k << " ";}cout << endl;//迭代区间删除元素s1.erase(s1.begin(), s1.find(5));for (auto k : s1){cout << k << " ";}cout << endl;//清空set中的元素s1.clear();for (auto k : s1){cout << k << " ";}cout << endl;return 0;
}

        运行结果如下:

        swap函数使用示例如下:

int main()
{//构造两个没有元素的空容器set<int> s1;set<int> s2;//s1中插入元素s1.insert(3);s1.insert(1);s1.insert(4);s1.insert(0);s1.insert(2);cout << "s1 : ";for (auto k : s1){cout << k << " ";}cout << endl;cout << "s2 : ";for (auto k : s2){cout << k << " ";}cout << endl;//交换s1和s2的值s1.swap(s2);cout << "s1 : ";for (auto k : s1){cout << k << " ";}cout << endl;cout << "s2 : ";for (auto k : s2){cout << k << " ";}cout << endl;return 0;
}

        运行结果如下:

        count()函数的定义如下图: 

      

        count函数使用示例如下:

int main()
{//构造一个没有元素的空容器set<int> s1;//s1中插入元素s1.insert(3);s1.insert(1);s1.insert(4);s1.insert(0);s1.insert(2);cout << "s1 : ";for (auto k : s1){cout << k << " ";}cout << endl;cout << s1.count(2) << endl;cout << s1.count(4) << endl;cout << s1.count(6) << endl;cout << s1.count(8) << endl;return 0;
}

        运行结果如下:


📌关联式容器multiset简介 

         我们先来看一下cplusplus.com - The C++ Resources Network网站对set的文档介绍:

        总结一下:

  1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
  2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。
  3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。
  4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。
  5. multiset底层结构为二叉搜索树(红黑树)

        注意:

  1. multiset中再底层中存储的是<value, value>的键值对
  2. mtltiset的插入接口中只需要插入即可
  3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的
  4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列
  5. multiset中的元素不能修改
  6. 在multiset中找某个元素,时间复杂度为$O(log_2 N)$
  7. multiset的作用:可以对元素进行排序

📌关联式容器multiset使用

        multiset的接口是和set一模一样的,区别在于具体的使用上:

        首先,multiset支持插入重复的键值key, 这就意味着multiset没有set的去重作用 :

int main()
{//构造一个没有元素的空容器setset<int> s;s.insert(3);s.insert(1);s.insert(5);s.insert(5);	//插入多个重复键值keys.insert(5);s.insert(4);s.insert(5);s.insert(2);for (auto e : s){cout << e << " ";}cout << endl;//构造一个没有元素的空容器multisetmultiset<int> ms;ms.insert(3);ms.insert(1);ms.insert(5);ms.insert(5);	//插入多个重复键值keyms.insert(5);ms.insert(4);ms.insert(5);ms.insert(2);for (auto e : ms){cout << e << " ";}cout << endl;return 0;
}

        运行结果如下:

        同时,对于set模板里几乎没有什么意义的几个函数接口在multiset这里就可以得到很好的应用了,如:count,equal_range等函数:

        如下代码,我们利用count函数计算multiset中5出现的次数,并利用equal_range函数将其全部删除:

int main()
{//构造一个没有元素的空容器multisetmultiset<int> ms;ms.insert(3);ms.insert(1);ms.insert(5);ms.insert(5);	//插入多个重复键值keyms.insert(5);ms.insert(4);ms.insert(5);ms.insert(2);for (auto e : ms){cout << e << " ";}cout << endl;//计算5出现的次数cout << "5出现的次数: " << ms.count(5) << endl;//删掉所有的5pair<multiset<int>::iterator, multiset<int>::iterator> ret = ms.equal_range(5);	//这里ret的类型直接用auto也行multiset<int>::iterator left = ret.first;multiset<int>::iterator right = ret.second;ms.erase(left, right);for (auto e : ms){cout << e << " ";}cout << endl;return 0;
}

        运行结果如下:


结语

希望这篇关于 STL标准模板库容器set 的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

相关文章推荐

【C++】模拟实现二叉搜索(排序)树

【数据结构】C语言实现链式二叉树(附完整运行代码)

【数据结构】什么是二叉搜索(排序)树?

【C++】模拟实现priority_queue(优先级队列)

【C++】模拟实现queue

【C++】模拟实现stack

【C++】模拟实现list

【C++】模拟实现vector

【C++】标准库类型vector

【C++】模拟实现string类

【C++】标准库类型string

【C++】构建第一个C++类:Date类

【C++】类的六大默认成员函数及其特性(万字详解)

【C++】什么是类与对象?


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1547940.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

s5pv210开发板刷机,分区,SD卡,emmc,nand,fastboot刷机命令,刷uboot,kernel,system(二)

一、x210开发板的启动机制 SD/inand启动步骤: 第一层启动从通道0&#xff0c;SD0(inand/emmc)启动, 当(inand/emmc)启动做校验和时失败才会转为启动通道2&#xff0c;SD2&#xff08;外接插入sd卡&#xff09;。而我们做裸机实验时是通过SD2来提供裸机程序镜像的&#xff0c;因…

SQL - 函数

1. 操作类函数 这一类函数针对数据结构&#xff0c;表格进行筛选操作 1.1 GROUP BY 根据某个单一列中属性或者多个列对结果集进行分组 SELECT column1, SUM(column2) FROM table GROUP BY column1; 上述代码将所选择列进行column1中的属性分组&#xff0c;作为每一行的索引…

“WanFangAi论文写作:智能论文助手,让研究更高效,论文写作技巧

点击查看本科毕业论文怎么搞&#xff01;【保姆级论文写作教程】 手把手教你从找文献到写作全流程 撰写论文是一个系统性的过程&#xff0c;需要一定的技巧和方法。即使没有经过正式的论文写作训练&#xff0c;大学生也可以通过以下步骤来学习如何写论文&#xff1a; ‌确定主题…

INTO:Web3世界的“价值引力场”

在Web3的宇宙中&#xff0c;一股强大的引力正在重塑整个数字世界的格局。这股引力&#xff0c;来自一个名为INTO的“超级连接器”。作为Web3社交领域的先锋&#xff0c;INTO正在用一种前所未有的方式重构整个产业链的价值体系。它不再满足于单一领域的创新&#xff0c;而是大胆…

u盘拷贝文件管控怎么设置?禁止往U盘拷贝文件的8种方法!(图文详解)

数字化时代&#xff0c;U盘作为便捷的数据存储与传输工具&#xff0c;其安全性不容忽视。 尤其在企业环境里&#xff0c;防止敏感数据通过U盘非法拷贝是保障信息安全的重要一环。 正所谓"小U盘大管控"&#xff0c;本文将详细介绍8种禁止往U盘拷贝文件的方法&#xf…

图片去除水印的简单方法,这6个图片去水印方法可以试试

在日常生活和工作中&#xff0c;我们常常需要从图片中去除水印&#xff0c;无论是为了保护隐私还是为了美化图像&#xff0c;去水印已经成为许多人必备的技能之一。然而&#xff0c;面对琳琅满目的去水印工具和方法&#xff0c;如何选择合适的解决方案可能让人感到困惑。在本文…

一文读懂SpringIoC的工作原理和机制(面试经)

导览 前言IoC(Inversion of Control)必学必看1. DI&#xff08;Dependency Injection&#xff09;2. IoC核心思想3. 创建Bean的方式3.1 构造函数3.2 构造静态方法3.3 构造实例工厂方法 4 依赖注入的方式4.1 setter注入4.2 构造方法注入4.3 接口注入 结语精彩回顾 前言 我们在使…

QDY421F-40C DN80 液动紧急切断阀

在深入探讨QDY421F-40C DN80液动紧急切断阀的优越性能时&#xff0c;不得不提及其在工业自动化与安全防护领域中的核心作用。这款阀门采用先进的液动驱动技术&#xff0c;能够在紧急情况下迅速响应&#xff0c;实现介质的快速切断&#xff0c;有效防止了潜在的事故扩大&#xf…

CSS链接

链接是网站的重要组成部分&#xff0c;几乎在每个网页上都能看到不少的链接&#xff0c;合理的设计链接的样式能够给网页的颜值加分。链接有四种不同的状态&#xff0c;分别是 link、visited、active 和 hover&#xff0c;可以通过以下伪类选择器来为链接的四种状态设置不同的样…

项目经理的“七宗罪”

项目经理作为团队的领导者&#xff0c;承担着确保项目按时、按质、按预算完成的重任。然而&#xff0c;即便是最经验丰富的项目经理&#xff0c;在追求项目成功的道路上也难免会遇到各种误区与挑战。 第一宗罪&#xff1a;盲目乐观 症状&#xff1a;对项目难度估计不足&#…

自己偷偷玩!(NSFW)无内容审查大模型推荐

大家好&#xff0c;我是画画的小强 今天给大家推荐几个(NSFW)无内容审查的大模型&#xff0c;可以让你部署在本地电脑运行&#xff01; CausalLM-14B CausalLM-14B 是基于阿里通义实验室的大模型 Qwen-14B 加入其他中文数据集训练而来&#xff0c;经过量化和 DPO 算法的重构…

Simple Calculator(简单计算器:算法初阶,代码基础,“纯”手撕)

简单计算器&#xff1a;仅适用无括号加减乘除&#xff0c;算法初阶&#xff0c;代码基础&#xff0c;不调库或模块“纯”手撕。 (笔记模板由python脚本于2024年09月22日 12:08:02创建&#xff0c;本篇笔记适合喜欢用python解决实际问题的coder翻阅) 【学习的细节是欢悦的历程】…

都说网络安全缺口那么大,但为何招聘数量却不多?总算明白了!

为啥网安领域缺口多达300多万人&#xff0c;但网安工程师也就是白帽黑客却很少&#xff0c;难道又是砖家在忽悠人&#xff1f; 原因主要为这三点: 首先是学校的原因&#xff0c;很多学校网络安全课程用的还都是十年前的老教材&#xff0c;教学脱离社会需求&#xff0c;实操技能…

AbMole揭秘3D类器官技术解锁SARS-CoV-2子宫内膜感染新视角

近期&#xff0c;一项由知名科研机构发起的研究&#xff0c;通过创新的3D类器官技术&#xff0c;深入剖析了SARS-CoV-2对子宫内膜的潜在影响&#xff0c;特别是其对垂直传播机制的独特见解&#xff0c;为疫情防控和妊娠安全提供了新的视角。 传统的研究方法受限于二维细胞培养…

牛牛的快递最小花费爬楼梯数组中两个字符串的最小距离

目录 1.牛牛的快递 2.最小花费爬楼梯 3.两个字符串的最小距离 1.牛牛的快递 牛牛的快递_牛客题霸_牛客网 算法思路&#xff1a; 这是一道非常简单的模拟题目&#xff0c;不多做介绍&#xff0c;扩展两个库函数&#xff0c;ceil()向上取整&#xff0c;floor()向下取整。 2.最…

思想和认知,从身边的事情和从小经历就在培养。谁在起跑线!

世界地图就像一张藏宝图&#xff0c;有的地方有宝藏&#xff0c;有的地方物资匮乏。当你拼命努力却一直挖不到宝藏的时候&#xff0c;不妨换个位置挖掘。如果你运气好&#xff0c;很可能就挖到一堆金子直接实现财富自由。运气不好&#xff0c;也能轻松过上小康生活。财富和位置…

低电平电压-电流转换器电路

1 简介 该电路可以为负载 RL 提供精确的低电平电流 IL。该设计由 5V 单电源供电&#xff0c;并使用一个精密低漂移运算放大器和一个仪表放大器。经过简单修改即可更改电压-电流 (V-I) 转换器的范围和精度。 2 设计目标 2.1 输入 2.2 输出 ​​​ 2.3 电源 2.4 负载电阻 3 电…

大规模数据处理:分库分表与数据迁移最佳实践

什么是分库分表 分库分表是一种数据库架构优化策略&#xff0c;它将数据分散存储在多个数据库或表中&#xff0c;以此来提高系统的可扩展性和性能。 虽然分库分表能够提升系统的整体性能&#xff0c;但是也不要一上来就分库分表&#xff0c;如果系统在单表的情况下&#xff0…

Python酷库之旅-第三方库Pandas(128)

目录 一、用法精讲 571、pandas.DataFrame.T属性 571-1、语法 571-2、参数 571-3、功能 571-4、返回值 571-5、说明 571-6、用法 571-6-1、数据准备 571-6-2、代码示例 571-6-3、结果输出 572、pandas.DataFrame.transpose方法 572-1、语法 572-2、参数 572-3、…

自建dns获取域名解析与证书告警

新钛云服已累计为您分享813篇技术干货 背 景 公司A拥有一套云上DNS服务&#xff0c;主要用于支持云中应用和服务的域名解析。为了满足线下门店之间的服务互联需求&#xff0c;公司在内网自建一套Windows DNS服务器&#xff0c;以实现门店之间的高效域名解析。此方案旨在保证内部…