C++——STL标准模板库——容器详解——set

一、基本概念

set容器是一种具备自动排序功能的集合,默认递增排序;元素无法直接修改,且不能重复;另一个版本叫做multiset,允许存在重复元素,其他功能和性质一样。

set容器底层结构一般为自平衡二叉搜索树,能够保证在O(logn)时间复杂度内完成删除、搜索、插入等操作。

set容器提供常量双向迭代器,不支持随机访问,不允许修改现有元素

二、构造函数

1、set<T>s;                                                默认构造函数

2、set<T>s={initializer _list}                       初始化列表构造

3、set<T>s(set<T>& other);                      复制构造函数

4、set<T>s(set<T>&& other);                    移动构造函数

5、set<T>s(iterator first,iterator last);        迭代器范围构造

6、set<T,Key_Compare>s(set<T>::key_comp& Par)        指定排序方式的构造函数,当构造自定义类型的容器时,必须指定排序方式。Key_Compare是一个指定排序方式的自定义类型,一般为类或者结构体,封装了定义排序方式的仿函数。例如指定递减排序:

class MyCompare {
public:bool operator()(const int&a, const int&b)const {return a > b;}
};set<int,MyCompare> s;        //对象后面参数省略
set<int,Mycompare> s1(s.key_comp());

在例子中模板参数列表中显式指定排序类型时,实例化对象参数可省略。 

set容器和前面其他容器一样,都重载了多种构造方式,可根据实际情况有选择使用。

三、成员函数

(一)迭代器函数

set<T>::iterator begin();                        返回指向容器首元素的迭代器

set<T>::iterator end();                           返回指向容器尾元素后面一个未知的迭代器

set容器提供的迭代器是双向迭代器,不支持随机访问。当然set也包括反向版本rbegin()、rend(),常量迭代器cbegin()、cend()等。

set容器提供的迭代器本质上都是常量迭代器,所以set容器不允许修改当前元素。

(二)大小相关函数

bool set<T>::empty();                        判断容器是否为空

size_t set<T>::size();                         返回容器当前元素个数

size_t set<T>::max_size();                返回set容器能够容纳元素的最大值

set容器没有容量的概念

(三)插入函数

STL源码中存在两种返回值的insert()函数,例:

1、iterator insert(T&value); 

2、Pair insert(T&value);

第二个版本的返回类型Pair为一个组合类型,包含<iterator,bool>两个结果,这种组合类型叫做对组;bool类型判断是否插入成功,iterator类型指向插入位置的迭代器,如果插入不成功指向end()。STL中通过条件编译实现了:set容器调用版本2,multiset容器调用版本1,从而实现了set容器元素唯一,multiset容器元素可重复。

insert();函数重载了以下几种插入方式。

insert(iterator pos,T&value);                迭代器指定插入位置,复制插入元素

insert(iterator pos,T&&value);             迭代器指定插入位置,移动插入元素

insert(iterator first,iterator last);           插入区间内的元素

insert(initializer _list);                           插入初始化列表

(四)删除函数

size_t erase(const T&value);                删除指定值,set返回1,multiset返回删除个数;

iterator erase(iterator pos);                   删除指定位置的值,返回指向该位置迭代器

iterator erase(iterator first,iterator last);删除指定区间,返回last;

四、使用注意事项

优势:

  1. 自动排序std::set 中的元素自动根据其值进行排序。你不需要像使用数组或链表那样手动排序。
  2. 唯一性std::set 只存储唯一的元素,这样可以确保数据的一致性,不会出现重复的数据。
  3. 高效的查找操作:由于 std::set 实现为红黑树,其查找、插入和删除操作的平均时间复杂度为 O(log n)。
  4. 标准容器std::set 是 C++ 标准库的一部分,因此与其它标准库组件有良好的兼容性。

劣势:

  1. 值的不可变性:一旦将一个元素插入到 std::set 中,你就不能更改该元素的值。如果你需要修改一个元素的值,你需要先删除旧的元素,然后插入新的元素。
  2. 内存使用:由于 std::set 需要为每个元素分配内存并维护一棵红黑树,所以它的内存使用可能会比其它容器(如数组或向量)更高。

使用时需要注意的事项:

  1. 元素的唯一性:由于 std::set 存储唯一的元素,如果你尝试插入一个已经存在的元素,std::set 将不会做任何事情,即不会插入重复的元素。因此,在插入元素之前,你可能需要检查元素是否已经存在于 set 中。
  2. 迭代器的稳定性std::set 的迭代器在删除元素后可能会失效。如果你在迭代过程中删除元素,可能会导致未定义的行为。为了安全地删除元素,你可以先保存要删除元素的迭代器,然后在迭代完成后再进行删除。
  3. 与其它容器的交互:当与其它容器(如 std::vector 或 std::list)进行交互时,需要注意 std::set 的特性。例如,将一个元素从一个 set 移动到另一个 set 或从 set 移动到另一个容器时,需要特别小心。
  4. 自定义比较函数std::set 需要一个比较函数来确定元素的排序和唯一性。确保你提供的比较函数是正确的,并且对于所有可能的输入都能产生一致的结果。

迭代器迭代过程删除元素实例

#include <iostream>  
#include <set>  int main() {  std::set<int> my_set = {1, 2, 3, 4, 5};  for (auto it = my_set.begin(); it != my_set.end(); ) {  if (*it == 3) {  it = my_set.erase(it); // 保存迭代器并删除元素  } else {  ++it; // 继续迭代  }  }  // 输出 set 中的元素  for (const auto& elem : my_set) {  std::cout << elem << " ";  }  std::cout << std::endl;  return 0;  
}

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

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

相关文章

低频信号发生器

前言 最近我快期末考试了&#xff0c;有点忙着复习。没时间写文章&#xff0c;不过学会了焊接 挺开心的所以买几套。 焊得怎么样这就是我们今天故事的主角“低频信号发生器”&#xff08;由于要用到所以这是购买链接&#xff09; 好&#xff0c;故事开始&#xff1a; 如何将…

手写一个starter来理解SpringBoot的自动装配

自动装配以及简单的解析源码 自动装配是指SpringBoot在启动的时候会自动的将系统中所需要的依赖注入进Spring容器中 我们可以点开SpringBootApplication这个注解来一探究竟 点开这个注解可以发现这些 我们点开SpringBootConfiguration这个注解 可以发现实际上SpringBootApp…

【网络取证篇】Windows终端无法使用ping命令解决方法

【网络取证篇】Windows终端无法使用ping命令解决方法 以Ping命令为例&#xff0c;最近遇到ping命令无法使用的情况&#xff0c;很多情况都是操作系统"环境变量"被改变或没有正确配置导致—【蘇小沐】 目录 1、实验环境&#xff08;一&#xff09;无法ping命令 &a…

Zabbix的多场景应用

1 zabbix更多用法 1.1 自动注册方式 zabbix自动发现 zabbix server服务端主动发现zappix agent客户端 1&#xff09;在【配置】-【自动发现】创建 发现规则&#xff0c;设置 IP范围 检查的键值system.uname 2&#xff09;在【配置】-【动作】-【发现动作】创建 动作&#x…

Leetcode1441.用栈操作构建数组

文章目录 题目原题链接思路代码 题目 给你一个数组 target 和一个整数 n。每次迭代&#xff0c;需要从 list { 1 , 2 , 3 …, n } 中依次读取一个数字。 请使用下述操作来构建目标数组 target &#xff1a; “Push”&#xff1a;从 list 中读取一个新元素&#xff0c; 并将其…

【面试突击】Spring 面试实战

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

2024年腾讯云服务器配置价格表(机型/磁盘/宽带/CPU)

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

SpringBoot教程(二) | 创建SpringBoot项目

SpringBoot教程(二) | 创建SpringBoot项目 接下来我们要学习一下如何创建一个spring boot项目。 我们采用的环境信息 JDK1.8 Maven 3.6 Idea 2021.1 所谓spring Boot项目&#xff0c;其实本质上就是一个maven/gradle项目&#xff0c;这是里面通过引入springBoot专门设置好…

JSP-概念

一、引子 很多读者可能听过JSP&#xff0c;并且知道这是一门过时的技术了。在Spring&#xff0c;SpringBoot已经成为主流的今天&#xff0c;笔者为什么还要介绍JSP的相关内容呢&#xff1f;笔者常常提到一个概念&#xff1a;理解一门技术&#xff0c;要理解这个技术为什么产生…

gin使用教程

文章目录 1、下载并安装 gin&#xff1a;2、快速例子3、示例3.1、AsciiJSON3.2、HTML 渲染3.3、JSONP3.4、Multipart/Urlencoded 绑定3.5、Multipart/Urlencoded 表单3.6、PureJSON3.7、Query 和 post form3.8、SecureJSON3.9、XML/JSON/YAML/ProtoBuf 渲染3.10、上传文件3.10.…

sqli-labs关卡23(基于get提交的过滤注释符的联合注入)

文章目录 前言一、回顾前几关知识点二、靶场第二十三关通关思路1、判断注入点2、爆数据库名3、爆数据库表4、爆数据库列5、爆数据库关键信息 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去…

给 Linux 主机添加 SSH 双因子认证

GitHub&#xff1a;https://github.com/google/google-authenticator-android 在信息时代&#xff0c;服务器安全愈发成为首要任务。Linux 主机通过 ssh 方式连接&#xff0c;当存在弱密码的情况下&#xff0c;通过暴力破解的方式会很容易就被攻破了&#xff0c;本文将向你展示…

国科大软件安全原理期末复习笔记

1 软件安全总论 1.软件的三大特性&#xff1a;复杂性、互连性、可扩展性&#xff1b; 2.基本概念&#xff1a;缺陷、漏洞、风险 缺陷&#xff08;bug&#xff09;&#xff1a;软件在设计和实现上的错误&#xff1b;漏洞&#xff08;vulnerability&#xff09;&#xff1a;漏洞…

解决虚拟机字体太小的问题

在win11中&#xff0c;安装VMWare软件后&#xff0c;创建好虚拟机&#xff0c;打开终端后&#xff0c;发现终端里显示的字体太小&#xff0c;不方便使用&#xff0c;因此需要修改。 1、打开终端 2、输入"gsettings set org.gnome.desktop.interface text-scaling-factor…

代码随想录算法训练营第五十二天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

代码随想录算法训练营第五十二天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组 最长递增子序列 300.最长递增子序列 文章讲解&#xff1a;https://programmercarl.com/0300.%E6%9C%80%E9%95%BF%E4%B8%8A%E5%8D%87%E5%AD%90%E5%BA%8F%E5%88%97.html 题目链…

Android 13.0仿ios的hotseat效果修改hotseat样式

1.概述 在13.0系统产品rom定制化开发中,在项目需求的需要,系统原生Launcher的布局样式很一般,所以需要重新设计ui对布局样式做调整,产品在看到 ios的hotseat效果觉得特别美观,所以要仿ios一样不需要横屏铺满的效果 居中显示就行了,所以就要看hotseat的具体布局显示了 效…

【MATLAB】CEEMD+FFT+HHT组合算法

代码原理 CEEMD&#xff08;集合经验模态分解&#xff09;FFT&#xff08;快速傅里叶变换&#xff09;HHT&#xff08;希尔伯特-黄变换&#xff09;组合算法也是一种常见的信号处理和分析方法。这种组合算法结合了CEEMD、FFT和HHT三个步骤&#xff0c;可以处理非线性和非平稳信…

react中概念性总结(三)

目录 React中事件绑定函数的方法有哪些? 函数如何传递参数&#xff1f; 什么是重绘与回流&#xff0c;触发条件&#xff0c;如何减少回流和重绘 React 生命周期中 getDerivedStateFromProps怎么使用&#xff0c;怎么理解&#xff1f; React中路由单页面应用的优缺点都有哪些…

Vue3+Vite项目搭建

为什么选择vite而不是vue-cli&#xff1a; vite下一代前端开发与构建工具 vite创建的项目默认vue3 优势&#xff1a; 开发环境中&#xff0c;无需打包&#xff0c;可快速的冷启动 轻量快速的热重载&#xff08;HMR&#xff09; 真正的按需编译&#xff0c;不在等待整个应用…

Android中两种选择联系人方式

1.在选择联系人方式网上也有很多案例 有的说是使用ContactsContract.CommonDataKinds.Phone.CONTENT_URI也有的说是使用ContactsContract.Contacts.CONTENT_URI其实这两种方式都可以使用 只不过ContactsContract.Contacts.CONTENT_URI这种方式需要多查询一遍 一、使用Contacts…