【C++】set详解

📢博客主页:https://blog.csdn.net/2301_779549673
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述

在这里插入图片描述

文章目录

  • 📢前言
  • 🏳️‍🌈 一、set类的介绍
  • 🏳️‍🌈二、set的构造和迭代器
  • 🏳️‍🌈三、set的增删查
  • 🏳️‍🌈四、insert和迭代器遍历使用样例
  • 👥总结


📢前言

Set 是 C++ 标准模板库(STL)中的一种关联容器,主要用于存储不重复且有序的元素。其内部实现采用红黑树,这种数据结构具有自动排序的特性,能够高效地进行插入、删除和查找操作。

红黑树是一种平衡二叉搜索树,它的统计性能优于一般的平衡二叉树。在 set 中,每个元素的值都唯一,并且元素的值不能直接被改变。这是因为 set 中的元素值就是其键值,关系到 set 元素的排列规则。如果任意改变 set 的元素值,会严重破坏 set 的组织。

Set 的迭代器被定义为底层红黑树的 const_iterator,杜绝了写入操作。这意味着我们不能通过 set 的迭代器直接修改元素的值。例如,当我们尝试通过 set 的迭代器改变元素的值时,编译器会报错。

此外,当对 set 进行元素新增操作(insert)或删除操作(erase)时,操作之前的所有迭代器,在操作完成之后都依然有效,被删除的那个元素的迭代器必然是个例外。这种特性使得 set 在进行动态操作时,能够保持迭代器的有效性,方便了程序的编写和维护。

总的来说,C++ 中的 set 容器以其独特的特性和高效的内部实现,为程序员提供了一种方便、可靠的数据存储和操作方式。


🏳️‍🌈 一、set类的介绍

  • set的声明如下,T就是set底层关键字的类型.
  • set默认要求T支持小于比较,如果不支持或者想按自己的需求走可以自行实现仿函数传给第二个模版参数
  • set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参数。
  • 一般情况下,我们都不需要传后两个模版参数。
  • set底层是用红黑树实现,增删查效率是O(l0gN),迭代器遍历是走的搜索树的中序,所以是有序的。
  • 前面部分我们已经学习了vector/list等容器的使用,STL容器接口设计,高度相似,所以这里我们就不再一个接口一个接口的介绍,而是直接带着大家看文档,挑比较重要的接口进行介绍。
template < class T, // set::key_type/value_typeclass Compare = less<T>, // set::key_compare/value_compareclass Alloc = allocator<T> // set::allocator_type> class set;

🏳️‍🌈二、set的构造和迭代器

  • set的构造我们关注以下几个接口即可。
  • set的支持正向和反向迭代遍历,遍历默认按升序顺序,因为底层是二叉搜索树,迭代器遍历走的中序;支持迭代器就意味着支持范围for,set的iterator和const iterator都不支持迭代器修改数据,修改关键字数据,破坏了底层搜索树的结构。

Set 的构造方式主要有以下几种:
默认构造函数:set st;,创建一个空的 set。例如:set mySet;。
拷贝构造函数:set(const set &st);,创建一个新的 set,它是现有 set 的副本。例如:set mySet = {1, 2, 3}; set anotherSet(mySet);。
使用区间构造:可以用一个已有的区间中的元素构造 set,如set s2(s1.begin(), s1.end());。
赋值操作可以使用重载的等号操作符:set& operator=(const set &st);,将一个 set 的内容赋值给另一个已经存在的 set。例如:set mySet = {1, 2, 3}; set anotherSet; anotherSet = mySet;。

// empty (1) ⽆参默认构造
explicit set (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
// range (2) 迭代器区间构造
template <class InputIterator>
set (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& = allocator_type());
// copy (3) 拷⻉构造
set (const set& x);
// initializer list (5) initializer 列表构造
set (initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
// 迭代器是⼀个双向迭代器
iterator -> a bidirectional iterator to const value_type
// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();

🏳️‍🌈三、set的增删查

set的增删查关注以下几个接口即可:

  • 插入元素
    使用insert方法可以在 set 中插入元素。例如:mySet.insert(5);。如果元素已存在,插入操作将被忽略。insert方法的返回值是个pair结构的对组,pair<iterator, bool>,bool 代表插入是否成功。当向 set 容器添加元素成功时,该迭代器指向 set 容器新添加的元素,bool 类型的值为 true;如果添加失败,即证明原 set 容器中已存有相同的元素,此时返回的迭代器就指向容器中相同的此元素,同时 bool 类型的值为 false。
  • 查找元素
    使用find方法查找 set 中元素。例如:auto it = mySet.find(element);,如果找到元素,it将指向该元素;否则,it将指向 set 的尾后。可以通过判断it是否等于end()来确定元素是否被找到。
  • 删除元素
    使用erase方法删除 set 中元素,有以下几种方式:
    删除迭代器指向的元素:erase(pos);,例如:auto it = mySet.find(3); if(it!= mySet.end()){ it = mySet.erase(it); }。
    删除指定值的元素:erase(elem);,例如:mySet.erase(4);。
    删除区间内的元素:erase(beg, end);。
  • 其他方法
    size():返回 set 中元素的数目。
    empty():判断 set 是否为空。如果为空,返回 true;否则返回 false。
    clear():清空 set 中的所有元素。
    lower_bound():返回大于或等于给定元素的第一个元素的迭代器。
    upper_bound():返回大于给定元素的第一个元素的迭代器。
    equal_range():返回一组迭代器,表示给定元素在 set 中的范围。
Member types
key_type -> The first template parameter (T)
value_type -> The first template parameter (T)
// 单个数据插⼊,如果已经存在则插⼊失败
pair<iterator, bool> insert (const value_type& val);
// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// 查找val,返回val所在的迭代器,没有找到返回end()
iterator find (const value_type& val);
// 查找val,返回Val的个数
size_type count (const value_type& val) const;
// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);
// 删除val,val不存在返回0,存在返回1
size_type erase (const value_type& val);
// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);
// 返回⼤于等val位置的迭代器
iterator lower_bound (const value_type& val) const;
// 返回⼤于val位置的迭代器
iterator upper_bound (const value_type& val) const;

易错点提示
end()函数的正确用法:end()函数的作用不是用于返回最后一个元素,而是用于返回 set 中最后一个元素的后一个位置的指针。如果一个 set 中的元素是<1,2,3>,那么返回的就是元素 3 之后的一位的指针。如果要看最后一个元素,可以使用遍历的方式找到最后一个元素,或者使用其他方法。

不能直接 copy:不能将一个 set 直接使用=号赋值给另外一个 set。如下面的写法就是错误的:set set1; set set2 = set1;。这种写法会导致编译错误或者不可预期的结果。在 C++ 中,set 的赋值操作需要使用特定的方法,如拷贝构造函数或者赋值运算符重载。

🏳️‍🌈四、insert和迭代器遍历使用样例

#include<iostream>
#include<set>
using namespace std;
int main() {
// 去重+升序排序set<int> s;
// 去重+降序排序(给⼀个⼤于的仿函数)
//set<int, greater<int>> s;s.insert(5);s.insert(2);s.insert(7);s.insert(5);
//set<int>::iterator it = s.begin();auto it = s.begin();while (it != s.end()) {// error C3892: “it”: 不能给常量赋值
// *it = 1;cout << *it << " ";++it;}cout << endl;
// 插⼊⼀段initializer_list列表值,已经存在的值插⼊失败s.insert({ 2, 8, 3, 9 });for (auto e : s) {cout << e << " ";}cout << endl;set<string> strset = { "sort", "insert", "add" };
// 遍历string⽐较ascll码⼤⼩顺序遍历的for (auto& e : strset) {cout << e << " ";}cout << endl;
}

👥总结


本篇博文对 set 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十三届蓝桥杯真题Python c组D.数位排序(持续更新)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;蓝桥杯关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 问题描述 小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。…

小川科技携手阿里云数据库MongoDB:数据赋能企业构建年轻娱乐生态

随着信息技术的飞速发展&#xff0c;企业在处理海量数据时所面临的挑战日益严峻。特别是在年轻娱乐领域&#xff0c;用户行为的多样性和数据量的激增对数据存储与分析技术提出了更高的要求。在此背景下&#xff0c;小川凭借其前瞻性的技术视野&#xff0c;选择了MongoDB作为其数…

手机二要素接口如何用C#实现调用

一、什么是手机二要素&#xff1f; 手机二要素又称运营商二要素&#xff0c;运营商二要素核验&#xff0c;实名核验&#xff0c;手机号核验&#xff0c;手机二要素核验&#xff0c;即传入姓名、手机号码&#xff0c;校验此两项是否一致。实时核验&#xff0c;返回校验结果&…

web应用合规(一)双因子认证2FA解决方案

文章目录 背景知识什么是2FA认证因子分类知识因素持有因素 解决方案密码 OTP密码 TOTP方案对比 参考文档后记 最近做海外项目&#xff0c;对合规方面的要求比较高&#xff0c;写一篇流水账来记录下 登录时的双因子认证过程&#xff0c;于是开启了2FA&#xff08;2 factor au…

jenkins 构建报错ERROR: Error fetching remote repo ‘origin‘

问题描述 修改项目的仓库地址后&#xff0c;使用jenkins构建报错 Running as SYSTEM Building in workspace /var/jenkins_home/workspace/【测试】客户端/client-fonchain-main The recommended git tool is: NONE using credential 680a5841-cfa5-4d8a-bb38-977f796c26dd&g…

【包教包会】CocosCreator3.x框架——音频声音模块(无需导入、无需常驻节点)

下载地址&#xff1a;AudioDemo3.x: CocosCreator3.x框架——音频模块 注意事项&#xff1a; 1、gi.musicPlay、gi.soundPlay是同步函数&#xff0c;使用前必须先将音频加载到缓存 Demo通过SceneLoading实现了一个极简的Loading页面&#xff0c;将音频全部加载后进入游戏&…

Find My汽车钥匙|苹果Find My技术与钥匙结合,智能防丢,全球定位

随着科技的发展&#xff0c;传统汽车钥匙向智能车钥匙发展&#xff0c;智能车钥匙是一种采用先进技术打造的汽车钥匙&#xff0c;它通过无线控制技术来实现对车门、后备箱和油箱盖等部件的远程控制。智能车钥匙的出现&#xff0c;不仅提升了汽车的安全性能&#xff0c;同时也让…

蓝桥杯—STM32G431RBT6(RTC时钟获取时间和日期)

一、RTC是什么&#xff0c;有什么用&#xff1f; 在 STM32 中&#xff0c;RTC&#xff08;Real-Time Clock&#xff0c;实时时钟&#xff09;主要有以下作用&#xff1a; 时间保持&#xff1a;即使在系统断电情况下&#xff0c;也能持续记录时间。&#xff08;需要纽扣电池供电…

LORA DASH -一种更高效的微调方式

LORA DASH -一种更高效的微调方式 概述 大型语言模型&#xff08;LLMs&#xff09;通过在大规模数据集上的预训练&#xff0c;能够捕捉和学习丰富的语言特征和模式。目前&#xff0c;尽管预训练模型在诸多任务上取得了显著的成果&#xff0c;但它们在特定任务上的表现仍有提升…

iOS--App启动过程及优化

前言 App启动是用户对于一个app的第一印象&#xff0c;因此如何使用户在最短的时间打开进入app显得格外重要。启动优化因此成为了App调优至关重要的一项。 只有具体了解了App的启动过程&#xff0c;我们才能对其进行优化。 App启动过程 App启动分为冷启动和热启动 热启动&…

【2025】springboot基于微信小程序记账本的设计与实现(源码+文档+调试+答疑)

文章目录 前言一、主要技术&#xff1f;二、项目内容1.整体介绍&#xff08;示范&#xff09;2.运行截图3.系统测试 总结更多项目 前言 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;记账本小…

臀部筋膜炎吃什么药最有效

臀部筋膜炎患者大多数会出现疼痛的症状&#xff0c;且疼痛程度可能会随着病情的加重而不断加重。疼痛可能表现为持续性或间歇性&#xff0c;严重时甚至可能出现针扎样疼痛。在疼痛的同时&#xff0c;如果按压臀部局部&#xff0c;可能会导致疼痛症状加剧。由于炎症刺激&#xf…

WPS在表格中填写材料时,内容过多导致表格不换页,其余内容无法正常显示 以及 内容过多,导致表格换页——解决方法

一、现象 1&#xff0c;内容过多导致表格不换页&#xff0c;其余内容无法正常显示 2&#xff0c;内容过多&#xff0c;导致表格换页 二、解决方法 在表格内右击&#xff0c;选择表格属性 在菜单栏选择行&#xff0c;勾选允许跨页断行&#xff0c;点击确定即可 1&#xff0…

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】 一、TFLM是什么&#xff1f;二、TFLM开源项目2.1 下载TFLM源代码2.2 TFLM基准测试说明2.3 TFLM基准测试命令 三、TFLM初步体验3.1 PC上运行Keyword基准测试3.2 PC上运行Person detection基准测试3.3 No module nam…

Redis篇(缓存机制 - 分布式缓存)(持续更新迭代)

目录 一、单点 Redis 的问题 1. 数据丢失问题 2. 并发能力问题 3. 故障恢复问题 4. 存储能力问题 5. 四种问题的解决方案 二、Redis持久化&#xff08;两种方案&#xff09; 1. RDB持久化 1.1. 简介 1.2. 执行时机 save命令 bgsave命令 停机时 触发RDB条件 1.3. …

phpstudy简易使用

注意&#xff0c;本文所述的操作步骤均建立在电脑上已经完成php环境变量的配置与vscode的安装之上 、

河南移动:核心营业系统稳定运行超300天,数据库分布式升级实践|OceanBase案例

河南移动&#xff0c;作为电信全业务运营企业&#xff0c;不仅拥有庞大的客户群体和业务规模&#xff0c;还引领着业务产品与服务体系的创新发展。河南移动的原有核心营业系统承载着超过6000万的庞大用户量&#xff0c;管理着超过80TB的海量数据&#xff0c;因此也面临着数据规…

网络安全法中,个人信息保护的措施和原则有哪些?

《中华人民共和国网络安全法》中关于个人信息保护的规定强调了几项基本原则和措施&#xff0c;以确保个人信息的安全。以下是其中的一些要点&#xff1a; 原则 合法性&#xff1a;个人信息的收集和使用必须符合法律规定。 正当性&#xff1a;信息收集和使用的目的是正当的&…

算法葫芦书(笔试面试)

一、特征工程 1.特征归一化&#xff1a;所有特征统一到一个区间内 线性函数归一化&#xff08;0到1区间&#xff09;、零均值归一化&#xff08;均值0&#xff0c;标准差1&#xff09; 2.类比型特征->数值性特征 序号编码、独热编码、二进制编码&#xff08;010&#xf…

数学建模--什么是数学建模?数学建模应该怎么准备?

前言 这是去年底学数学建模老哥的建模课程笔记&#xff1b;未来本人将陆陆续续的更新数学建模相关的一些基础算法&#xff0c;大家可以持续关注一下&#xff1b;提示&#xff1a;数学建模只有实战才能提升&#xff0c;光学算法没有啥意义&#xff0c;也很难学的很懂。 文章目录…