set、map、multiset、multimap容器介绍和常用接口使用

文章目录

    • 前言
    • 一、set容器
    • 二、multiset
    • 三、map
    • 四、multimap


前言

1、set、map、 multiset、 multimap都是基于红黑树实现的容器。
2、set、multiset都使用头文件#include<set>,map、multimap都是使用头文件#include<map>

一、set容器

1、set容器的介绍

C++标准库中的set容器是一种关联容器,它存储的元素是唯一的,并且以特定的顺序排列。set容器基于红黑树实现,这意味着它可以提供对数时间复杂度的插入、删除和查找操作。

2、set容器的特性

(1)唯一性:set中的每个元素都必须是唯一的,因为set通过其值来标识元素,而不是通过位置或索引。
(2)自动排序:set中的元素会根据其值自动排序。默认情况下,使用元素类型的<运算符进行排序,但可以指定自定义的比较函数来改变排序规则。
(3)对数时间复杂度:插入、删除和查找操作的时间复杂度为O(log n),其中n是容器中元素的数量。
(4)不支持直接元素访问:与vector或deque等序列容器不同,set不支持通过位置直接访问元素。要访问元素,必须使用迭代器或通过其值来查找。
(5) 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放
value,但在底层实际存放的是由<value, value>构成的键值对
(6) set中插入元素时,只需要插入value即可,不需要构造键值对。
(7)不支持修改元素:因为set的设计初衷是为了维护一个唯一且自动排序的元素集合。如果允许直接修改 元素的值,那么可能会破坏set的这两个核心特性:
唯一性:set中的每个元素都必须是唯一的。如果允许修改元素的值,那么可能会使得原本唯一的元素变得不唯一,比如将一个元素修改为set中已存在的另一个元素的值。
自动排序:set中的元素会根据其值自动排序。如果允许修改元素的值,那么可能会破坏原有的排序顺序,使得set无法再按照预期的顺序来遍历或查找元素。

3、set容器使用
(1)模板参数:
在这里插入图片描述

T: set中存放元素的类型,实际在底层存储<value, value>的键值对。
Compare:set中元素默认按照小于来比较。
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理
注意:一般只传第一个参数,如果需要按照特定条件排序可以自定义一个比较仿函数作为第二个参数,第三个基本不用传。

(2)常用构造、赋值接口

函数声明功能
set (const Compare& comp = Compare(), const Allocator& = Allocator() );构造空的set
set (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator() );用[first, last)区间中的元素构造set
set ( const set<Key,Compare,Allocator>& x);set的拷贝构造
set& operator= (const set& x);进行赋值

使用:

//无参构造构造
set<int> set1;//迭代区间构造
vector<int> v = { 1,2,3,4,5 };
set<int> set2(v.begin(), v.end());//拷贝构造
set<int> set3(set2);//赋值
set<int> set4;
set4 = set3;

(3)常用迭代器接口

set迭代器是双向迭代器,只支持++或者–操作,不支持随机访问。

函数声明功能
iterator begin()返回第一个元素的迭代器
iterator end()返回最后一个元素的下一个位置的迭代器

使用:

void test02()
{//迭代区间构造vector<int> v = { 1,2,3,4,5 };set<int> set1(v.begin(), v.end());//迭代器//指向第一个元素的迭代器set<int>::iterator it1 = set1.begin();//指向最后一个元素的迭代器set<int>::iterator it2 = set1.end();//通过迭代器遍历while (it1 != it2){cout << *it1 << " ";it1++;}cout << endl;
}

(4)常用插入、删除、查找接口

函数声明功能
pair<iterator,bool> insert (const value_type& val);在set中插入元素x,实际插入的是<x, x>构成的键值对,如果插入成功,返回该元素在set中的位置,true>,如果插入失败,说明x在set中已经存在,返回<x在set中的位置,false>
iterator erase (const_iterator position);删除set中position位置上的元素,返回值是一个迭代器,指向被删除元素之后的元素。如果 position 指向的是 set 中的最后一个元素,那么返回的迭代器将等于 set 的 end() 迭代器
size_type erase ( const key_type& x )删除set中值为x的元素,返回删除的元素的个数
void clear() noexcept;清空
iterator find (const value_type& val);返回set中值为x的元素的位置,找不到返回end()

使用:

//插入、删除、查找
void test03()
{//set<int> set1;//插入set1.insert(1);set1.insert(2);set1.insert(3);set1.insert(4);set1.insert(5);cout << "插入:";set<int>::iterator it1 = set1.begin();//通过迭代器遍历while (it1 != set1.end()){cout << *it1 << " ";it1++;}cout << endl;//通过迭代器遍历删除set<int> set2(set1);cout << "迭代器遍历删除:";set<int>::iterator it2 = set2.begin();//通过迭代器遍历while (it2 != set2.end()){it2 = set2.erase(it2);}cout << endl;cout << "键值删除:";set<int> set3(set1);set3.erase(1);set3.erase(3);set<int>::iterator it3 = set3.begin();//通过迭代器遍历while (it3 != set3.end()){cout << *it3 << " ";it3++;}cout << endl;//查找set<int> set4(set1);cout << "查找:";auto it4 = set4.find(2);if (it4 != set4.end())cout << *it4 << endl;elsecout << "找不到!" << endl;}

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6089873670c6404aa29357967039c526.png

(5)常用大小相关接口

函数声明功能
size_type count ( const key_type& x ) const返回set中值为x的元素的个数
bool empty() const noexcept;判断是否为空
size_type size() const noexcept;返回元素个数
使用:
void test04()
{vector<int> v = { 1,2,3,4,5 };set<int> set1(v.begin(), v.end());cout << "大小:" << set1.size() << endl;cout << "1的个数:" << set1.count(1) << endl;if (!set1.empty())cout << "不为空" << endl;elsecout << "为空" << endl;
}

二、multiset

1、multiset介绍

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

2、set与multiset区别

(1)set容器不能出现重复元素,multiset能出现重复元素。
(2)两者容器接口相同,count接口对于set来说不是1就是0,而对于multiset可以是实际元素个数,find接口对于set来说查找的元素是唯一的,而对于multiset来说查找的元素如果存在多个就返回红黑树中序遍历的第一个。

3、使用

//multiset
void test05()
{vector<int> v = { 1,1,3,4,5,2,4,4,4 };multiset<int> mset1(v.begin(), v.end());cout << "4的个数" << mset1.count(4)<<endl;multiset<int>::iterator mit = mset1.begin();//通过迭代器遍历while (mit != mset1.end()){cout << *mit << " ";mit++;}cout << endl;}

三、map

1、map介绍

C++中的map容器是一种关联容器,它存储的元素是一对键值(key-value)对(使用对组pair)。每个键值对映射一个特定的键到一个特定的值。在map中,任何两个键都不能相同,因为每个键只能映射到一个值。map中的元素总是按照键的顺序排序。

2、map特征

(1)自动排序:map中的元素会根据键自动排序。默认情况下,它使用<运算符来比较键,所以键类型需要支持这个运算符。
(2)唯一键:每个键在map中必须是唯一的。
(3)直接访问:可以通过键直接访问元素。
(4)map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

3、接口使用
(1)模板参数
在这里插入图片描述

key: 键值对中key的类型
T: 键值对中value的类型
Compare:比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的 空间配置器

(1)常用构造、赋值接口

函数声明功能
map()空构造
map (const map& x);拷贝构造
map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type());用迭代区间构造
map& operator= (map&& x);赋值

使用:

//赋值,
//构造
void test06()
{//迭代区间构造vector<pair<int, int>> v = { {1,1},{2,2},{3,3} };map<int,int> mp1(v.begin(), v.end());//空构造map<int, int> mp2;//拷贝构造map<int, int> mp3(mp1);//赋值map<int, int> mp4;mp4 = mp1;
}

(2)常用迭代器接口

map迭代器是双向迭代器,只支持++或者–操作,不支持随机访问。

函数声明功能
begin()begin:首元素的位置
end()end最后一个元素的下一个位置

使用:

迭代器
void test07()
{//迭代区间构造vector<pair<int, int>> v = { {1,1},{2,2},{3,3} };map<int, int> mp1(v.begin(), v.end());//迭代器遍历map<int, int>::iterator it = mp1.begin();while (it != mp1.end()){cout << it->first << " ";it++;}cout << endl;
}

(3)常用插入、删除、修改、查找接口

函数声明功能
pair<iterator,bool> insert ( const value_type& x )在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表释放插入成功
void erase ( iterator position )删除position位置上的元素
size_type erase ( const key_type& x )删除键值为x的元素,返回删除元素个数
void clear ( )清空
iterator find ( const key_type& x )在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end
mapped_type& operator[] (const key_type& k);重载[],通过key返回value的引用,不用在key是相当于插入,value会调用其默认构造进行初始化

使用:

//插入等操作
void test08()
{map<int, int> mp1;//插入pair对象mp1.insert({ 1,1 });mp1.insert({ 2,2 });mp1.insert({ 3,3 });mp1.insert({ 4,4 });cout << "插入后:";map<int, int>::iterator it1 = mp1.begin();while (it1 != mp1.end()){cout << it1->first << " ";it1++;}cout << endl;//通过key删除mp1.erase(1);//通过迭代器删除map<int, int>::iterator it2 = mp1.begin();//mp1.erase(it2);cout << "删除后:";map<int, int>::iterator it3 = mp1.begin();while (it3 != mp1.end()){cout << it3->first << " ";it3++;}cout << endl;//查找map<int, int>::iterator it4 = mp1.find(3);if (it4 != mp1.end())cout << "存在" << endl;elsecout << "不存在" << endl;//通过[key]进行修改valuemp1[3] = 1000;//修改为1000cout << "修改后:" << mp1[3] << endl;
}

在这里插入图片描述
(4)常用大小相关的接口

函数声明功能
size_type count ( const key_type& x ) const返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中
size_type size() const;返回元素个数
bool empty() const;判断是否为空

使用:

void test09()
{//迭代区间构造vector<pair<int, int>> v = { {1,1},{2,2},{3,3} };map<int, int> mp1(v.begin(), v.end());cout << "大小:" << mp1.size() << endl;cout << "4的个数:" << mp1.count(4) << endl;if (!mp1.empty())cout << "不为空" << endl;elsecout << "为空" << endl;
}

在这里插入图片描述

四、multimap

1、multimap介绍

  1. Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对<key, value>,其中多个键值对之间的key是可以重复的。
  2. 在multimap中,通常按照key排序和惟一地标识元素,而映射的value存储与key关联的内 容。key和value的类型可能不同,通过multimap内部的成员类型value_type组合在一起,
    value_type是组合key和value的键值对: typedef pair<const Key, T> value_type;
  3. 在内部,multimap中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对 key进行排序的。
  4. multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代 器直接遍历multimap中的元素可以得到关于key有序的序列。
  5. multimap在底层用二叉搜索树(红黑树)来实现。

2、map与multimap的区别

(1)multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的。
(2)接口multimap少了 at()、[ ]重载,count(key)接口对于map来说不是1就是0,对于multimap来说还可以是多个,find(key)接口对于map来说存在唯一值,对于multimap来说如果存在多个相同的key就会返回红黑树中序遍历的第一个,其他接口基本一样。

3、使用

void test10()
{//迭代区间构造vector<pair<int, int>> v = { {1,1},{2,2},{3,3},{2,2},{2,2} };multimap<int, int> mp1(v.begin(), v.end());cout << "2的个数:" << mp1.count(2) << endl;//迭代器遍历multimap<int, int>::iterator it = mp1.begin();while (it != mp1.end()){cout << it->first << " ";it++;}cout << endl;}

在这里插入图片描述

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

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

相关文章

pytest常用命令行参数解析

简介&#xff1a;pytest作为一个成熟的测试框架&#xff0c;它提供了许多命令行参数来控制测试的运行方式&#xff0c;以配合适用于不同的测试场景。例如 -x 可以用于希望出现错误就停止&#xff0c;以便定位和分析问题。–rerunsnum适用于希望进行失败重跑等个性化测试策略。 …

【BUG】已解决:AttributeError: ‘str‘ object has no attribute ‘get‘

已解决&#xff1a;AttributeError: ‘str‘ object has no attribute ‘get‘ 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c…

C++初学者指南-5.标准库(第一部分)--标准库查找算法

C初学者指南-5.标准库(第一部分)–标准库查找算法 文章目录 C初学者指南-5.标准库(第一部分)--标准库查找算法查找/定位一个元素findfind_iffind_if_notfind_last / find_last_if / find_last_if_notfind_first_of 查找范围内的子范围 search find_endstarts_withends_with 找到…

SpringBoot3 + Vue3 学习 Day 2

登入接口 和 获取用户详细信息的开发 学习视频登入接口的开发1、登入主逻辑2、登入认证jwt 介绍生成 JWT① 导入依赖② 编写代码③ 验证JWT 登入认证接口的实现① 导入 工具类② controller 类实现③ 存在的问题及优化① 编写拦截器② 注册拦截器③ 其他接口直接提供服务 获取用…

Web3D:WebGL为什么在渲染性能上输给了WebGPU。

WebGL已经成为了web3D的标配&#xff0c;市面上有N多基于webGL的3D引擎&#xff0c;WebGPU作为挑战者&#xff0c;在渲染性能上确实改过webGL一头&#xff0c;由于起步较晚&#xff0c;想通过这个优势加持&#xff0c;赶上并超越webGL仍需时日。 贝格前端工场为大家分享一下这…

Webstorm-恢复默认UI布局

背景 在使用Webstorm的时候,有时候进行个性化设置,如字体、界面布局等. 但是设置后的效果不理想,想要重新设置回原来的模样,却找不到设置项. 这里提供一种解决方案,恢复默认设置,即恢复到最初刚下载好后的设置. 操作步骤 步骤一:打开setting 步骤二:搜索Restore Default,找到…

数学建模-----SPSS参数检验和非参数检验

目录 1.参数检验 1.1独立样本t检验案例分析 1.1.1查看数据编号 1.1.2确定变量所属类型 1.1.3选项里面的置信区间 1.1.4对于结果进行分析 1.2配对样本t检验案例分析 1.2.1相关设置 1.2.2分析结果 2.非参数检验 2.1对比分析 2.2非参数检验的方法 2.3案例分析 2.3.1相…

10道JVM经典面试题

1、 JVM中&#xff0c;new出来的对象是在哪个区&#xff1f; 2、 说说类加载有哪些步骤&#xff1f; 3、 JMM是什么&#xff1f; 4、 说说JVM内存结构&#xff1f; 5、 MinorGC和FullGC有什么区别&#xff1f; 6、 什么是STW? 7、 什么情况下会发生堆/栈溢出&#xff1f…

当“广撒网”遇上“精准定点”的鱼叉式网络钓鱼

批量网络钓鱼电子邮件活动倾向于针对大量受众&#xff0c;它们通常使用笼统的措辞和简单的格式&#xff0c;其中不乏各种拼写错误。而有针对性的攻击往往需要付出更大的努力&#xff0c;攻击者会伪装成雇主或客户向目标发送包含个人详细信息的个性化消息。在更大范围内采用这种…

大语言模型-文本检索任务基准 BEIR

BEIR (A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models) 文本检索任务的基准&#xff0c;使用18 个数据集为检索系统的零样本评估提出了一个标准化基准&#xff0c; BEIR 基准上在9个不同领域的检索任务评估 10 种不同的检索方法。 九个…

义务外贸wordpress独立站主题

健身器材wordpress网站模板 跑步机、椭圆机、划船机、动感单车、健身车、深蹲架、龙门架、健身器材wordpress网站模板。 https://www.jianzhanpress.com/?p4251 农业机械wordpress网站模板 植保机械、畜牧养殖机械、农机配件、土壤耕整机械、农业机械wordpress网站模板。 …

2.1.卷积层

卷积 ​ 用MLP处理图片的问题&#xff1a;假设一张图片有12M像素&#xff0c;那么RGB图片就有36M元素&#xff0c;使用大小为100的单隐藏层&#xff0c;模型有3.6B元素&#xff0c;这个数量非常大。 识别模式的两个原则&#xff1a; 平移不变性&#xff08;translation inva…

K8S 部署jaeger-operator,与其演示项目hotrod

最近在研究observabilty在K8S环境的onboard&#xff0c;查阅了一些资料&#xff0c;发现现在网上Prometheus/Metrics相关的资源&#xff0c;是比较全面的&#xff0c;而Trace相关的部分不是很全面&#xff0c;所以写下这篇博文&#xff0c;以做备忘和分享。 组件介绍 我这里选…

Excel的操作

Excel的操作 一、Excel的作用 Excel是一款功能强大的电子表格软件&#xff0c;主要用于数据处理和分析。 二、Excel的基础操作 新建文档 一般情况下&#xff0c;就在桌面空白处&#xff0c;点击鼠标右键&#xff0c;即可新建 三、页面布局 1、快速访问工具栏 主要包含&am…

为 android编译 luajit库、 交叉编译

时间&#xff1a;20200719 本机环境&#xff1a;iMac2017 macOS11.4 参考: 官方的文档&#xff1a;Use the NDK with other build systems 写在前边&#xff1a;交叉编译跟普通编译类似&#xff0c;无非是利用特殊的编译器、链接器生成动态或静态库; make 本质上是按照 Make…

ssm 学习 ---(spring)

一、spring框架 1、基本框架 2、Beanfactory快速入门 配置清单&#xff1a;xml文件 (1) 导入jar包或者maven坐标 (2) 定义UserService接口以及UserService实现类 (3) 创建bean.xml配置文件&#xff0c;将UserService信息配置到该xml文件中; (4)编写测试代码&#xff0c;创…

ubuntu lxqt触摸屏旋转校准(usb触摸屏、lxqt、ubuntu23.10)

参考文章&#xff1a;https://www.codetd.com/article/5651388 1.查看触摸屏驱动 rootxyy:~# xinput list ⎡ Virtual core pointer id2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id4 [slave pointer (2)…

如何根据同一行的ID利用R语言对值进行求和

需求&#xff1a;将属于同一分组的对应的值进行求和或者求平均值 #设置工作目录 > getwd() [1] "C:/Users/86150/Documents" > setwd("C:/Users/86150/Desktop/AA2024/RUF") > list.files() #读取文件 >install.packages("readxl")…

基于NeRF的路面重建算法——RoME / EMIE-MAP / RoGS

基于NeRF的路面重建算法——RoME / EMIE-MAP / RoGS 1. RoMe1.1 Mesh Initialization / Waypoint Sampling1.2 Optimization1.3 Experiments 2. EMIE-MAP2.1 Road Surface Representation based on Explicit mesh and Implicit Encoding2.2 Optimizing Strategies2.3 Experimen…

在 CI/CD Pipeline 中实施持续测试的最佳实践!

随着软件开发周期的不断加快&#xff0c;持续集成&#xff08;CI&#xff09;和持续交付/部署&#xff08;CD&#xff09;已经成为现代软件开发的重要组成部分。在这一过程中&#xff0c;持续测试的实施对于确保代码质量、提高发布效率至关重要。本文将详细介绍在CI/CD流水线中…