【C++ STL之map,set,pair详解】
目录
- 一.map映射
- 1.简介
- 2.包含头文件及其初始化
- 3.基本操作
- 4.用迭代器正反遍历
- 5.添加元素的四种方式
- 6.元素的访问
- 7.对比unordered_map,multimap
- 二.set集合
- 1.简介
- 2.包含头文件及其初始化
- 3.基本操作
- 4.元素的访问
- 5.set,multiset,unordered_set,unordered_multiset 比较
- 三.pair二元组
- 1.简介
- 2.包含头文件及其初始化
- 3.访问与修改
一.map映射
1.简介
在C++的STL(Standard Template Library)中,map是一个非常有用的关联容器。它提供了一种键-值对的数据结构,其中的元素按照键的顺序进行排序,并且每个键是唯一的。本文将详细介绍C++ STL中map的使用方法和一些常见操作。
2.包含头文件及其初始化
(1)头文件
#include <map>
(2)初始化方法
可以使用以下方式声明和初始化一个map对象:
map<KeyType, ValueType> myMap; // 声明一个空的map
map<string,string> mp;
map<string,int> mp;
map<int,node> mp;//node是结构体类型
也可以使用已有的键值对初始化map对象
std::map<KeyType, ValueType> myMap = {{key1, value1},{key2, value2},{key3, value3}
};
3.基本操作
代码 | 含义 |
---|---|
mp.find(key) | 返回键为key的映射的迭代器 注意:用find函数来定位数据出现位置,它返回一个迭代器。当数据存在时,返回数据所在位置的迭代器,数据不存在时,返回mp.end() |
mp.erase(it) | 删除迭代器对应的键和值 |
mp.erase(key) | 根据映射的键删除键和值 |
mp.erase(first,last) | 删除左闭右开区间迭代器对应的键和值 |
mp.size() | 返回映射的对数 |
mp.clear() | 清空map中的所有元素 |
mp.insert() | 插入元素,插入时要构造键值对 |
mp.empty() | 如果map为空,返回true,否则返回false |
mp.begin() | 返回指向map第一个元素的迭代器 |
mp.end() | 返回指向map尾部的迭代器(最后一个元素的下一个地址) |
mp.rbegin() | 返回指向map最后一个元素的反向迭代器 |
mp.rend() | 返回指向map第一个元素前面(上一个)的反向迭代器(地址) |
mp.count(key) | 查看元素是否存在,存在返回1,不存在返回0 |
mp.lower_bound() | 返回一个迭代器,指向键值>= key的第一个元素(只比较键) |
mp.upper_bound() | 返回一个迭代器,指向键值> key的第一个元素(只比较键) |
接下来将给出相对应代码来帮助理解
(1)使用insert()函数添加单个键值对:
myMap.insert(std::make_pair(key, value));
(2)使用下标运算符[ ]添加或更新键值对:
myMap[key] = value;
(3)使用erase()函数删除指定键的元素:
myMap.erase(key);
(4)使用find()函数查找指定键的元素,返回指向该元素的迭代器:
auto it = myMap.find(key);
if (it != myMap.end()) {// 找到了该键对应的元素ValueType value = it->second;
}
(5)使用lower_bound()函数查找大于等于指定键的第一个元素的迭代器:
auto it = myMap.lower_bound(key);
if (it != myMap.end()) {// 找到了大于等于指定键的第一个元素KeyType foundKey = it->first;ValueType foundValue = it->second;
}
(6)使用upper_bound()函数查找大于指定键的第一个元素的迭代器:
auto it = myMap.upper_bound(key);
if (it != myMap.end()) {// 找到了大于指定键的第一个元素KeyType foundKey = it->first;ValueType foundValue = it->second;
}
4.用迭代器正反遍历
(正向遍历)
map<int,int> mp;
mp[1] = 2;
mp[2] = 3;
mp[3] = 4;
auto it = mp.begin();
while(it != mp.end())
{cout << it->first << " " << it->second << "\n";it ++;
}
(反向遍历)
map<int,int> mp;
mp[1] = 2;
mp[2] = 3;
mp[3] = 4;
auto it = mp.rbegin();
while(it != mp.rend())
{cout << it->first << " " << it->second << "\n";it ++;
}
5.添加元素的四种方式
//先声明
map<string,string> mp;
mp["学习"] = "看书";//第一种
mp["玩耍"] = "打游戏";
mp.insert(make_pair("vegetable","蔬菜"));//第二种
mp.insert(pair<string,string>("fruit","水果"));//第三种
mp.insert({"hahaha","wawawa"});//第四种
6.元素的访问
(1)迭代器访问
int main() {std::map<int, std::string> myMap = {{1, "Alice"},{2, "Bob"},{3, "Charlie"}};// 使用迭代器进行遍历和访问for (auto it = myMap.begin(); it != myMap.end(); ++it) {int key = it->first; // 访问键string value = it->second; // 访问值cout << key << ": " << value << std::endl;}return 0;
}
(2)智能指针访问
for(auto i : mp)
cout << i.first << " " << i.second << endl;//键,值
(3)单个访问
map<char,int>::iterator it = mp.find('a');
cout << it -> first << " " << it->second << "\n";
(4)c++17特性才具有
for(auto [x, y] : mp)cout << x << " " << y << "\n";
//x,y对应键和值
7.对比unordered_map,multimap
1.map:map是一个有序的关联容器,其中的元素按照键的顺序进行排序。每个键是唯一的,不允许重复。map使用红黑树实现,插入和查找操作的时间复杂度为O(log n)。
2.unordered_map:unordered_map是一个无序的关联容器,其中的元素没有特定的顺序。每个键是唯一的,不允许重复。unordered_map使用哈希表实现,插入和查找操作的平均时间复杂度为O(1),最坏情况下为O(n)。(也是用哈希表实现)
3.multimap:multimap是一个有序的关联容器,其中的元素按照键的顺序进行排序。允许键重复,即可以有相同的键。multimap使用红黑树实现,插入和查找操作的时间复杂度为O(log n)。
4.unordered_multimap:unordered_multimap是一个无序的关联容器,其中的元素没有特定的顺序。允许键重复,即可以有相同的键。unordered_multimap使用哈希表实现,插入和查找操作的平均时间复杂度为O(1),最坏情况下为O(n)。
对比优劣:
(1)map和unordered_map都提供了快速的查找操作,但是在插入和删除操作上,unordered_map通常比map更快。
(2)unordered_map的元素没有特定的顺序,适用于不需要保持顺序的场景。而map的元素是有序的,适用于需要按照键的顺序进行访问的场景。
(3)multimap和unordered_multimap允许键重复,适用于需要存储相同键的场景。multimap保持元素的有序性,而unordered_multimap没有特定的顺序。
(4)在空间占用上,哈希表实现的容器(unordered_map和unordered_multimap)通常需要更多的内存,而红黑树实现的容器(map和multimap)通常需要较少的内存。
选择使用哪种容器取决于具体的需求。如果需要有序访问或者需要保持元素的有序性,可以选择map或multimap。如果对元素的顺序没有特定要求,但需要快速的插入和查找操作,可以选择unordered_map或unordered_multimap。
二.set集合
1.简介
在C++的STL(Standard Template Library)中,set是一个非常有用的关联容器。它提供了一种有序集合的数据结构,其中的元素按照键的顺序进行排序,并且每个键是唯一的。本文将详细介绍C++ STL中set的使用方法和一些常见操作。
2.包含头文件及其初始化
(1)头文件
#include <set>
(2)初始化
std::set<KeyType> mySet; // 声明一个空的set
std::set<KeyType> mySet = {element1, element2, element3};//也可以使用已有的元素初始化set对象:
3.基本操作
代码 | 含义 |
---|---|
s.begin() | 返回set容器的第一个元素的地址(迭代器) |
s.end() | 返回set容器的最后一个元素的下一个地址(迭代器) |
s.rbegin() | 返回逆序迭代器,指向容器元素最后一个位置 |
s.rend() | 返回逆序迭代器,指向容器第一个元素前面的位置 |
s.clear() | 删除set容器中的所有的元素,返回unsigned int类型 |
s.empty() | 判断set容器是否为空 |
s.insert() | 插入一个元素 |
s.size() | 返回当前set容器中的元素个数 |
erase(iterator) | 删除定位器iterator指向的值 |
erase(first,second) | 删除定位器first和second之间的值(左闭右开) |
erase(key_value) | 删除键值key_value的值 |
s.find(元素) | 查找set中的某一元素,有则返回该元素对应的迭代器,无则返回end() |
s.lower_bound(k) | 返回大于等于k的第一个元素的迭代器 |
s.upper_bound(k) | 返回大于k的第一个元素的迭代器访问 |
接下来将给出相对应代码来帮助理解
1.插入元素
mySet.insert(element);
mySet.insert(beginIterator, endIterator);2.删除元素
mySet.erase(value);
mySet.erase(beginIterator, endIterator);//注意左闭右开3.查找元素
auto it = mySet.find(value);
if (it != mySet.end()) {// 找到了该值对应的元素
}auto it = mySet.lower_bound(value);
if (it != mySet.end()) {// 找到了大于等于指定值的第一个元素
}auto it = mySet.upper_bound(value);
if (it != mySet.end()) {// 找到了大于指定值的第一个元素
}
4.元素的访问
(1)迭代器访问
for(set<int>::iterator it=s.begin();it!=s.end();it++)cout<<*it<<" ";
(2)智能指针
for(auto i : s)cout<<i<<endl;
(3)访问最后一个元素
//第一种
cout<<*s.rbegin()<<endl;//第二种
set<int>::iterator iter = s.end();
iter--;
cout<<(*iter)<<endl; //打印2;//第三种
cout<<*(--s.end())<<endl;
5.set,multiset,unordered_set,unordered_multiset 比较
1.set:有序的关联容器,每个元素都是唯一的。使用红黑树实现,插入和查找的时间复杂度为O(log n)。元素按照键的顺序进行排序。
2.multiset:有序的关联容器,允许元素重复。使用红黑树实现,插入和查找的时间复杂度为O(log n)。元素按照键的顺序进行排序。
3.unordered_set:无序的关联容器,每个元素都是唯一的。使用哈希表实现,插入和查找的平均时间复杂度为O(1),最坏情况下为O(n)。元素没有特定的顺序。
4.unordered_multiset:无序的关联容器,允许元素重复。使用哈希表实现,插入和查找的平均时间复杂度为O(1),最坏情况下为O(n)。元素没有特定的顺序。
总结:
set和multiset是有序的,元素按照键的顺序进行排序,multiset允许元素重复。
unordered_set和unordered_multiset是无序的,元素没有特定的顺序,unordered_multiset允许元素重复。
set和unordered_set的查找和插入操作的时间复杂度较低,适用于需要快速查找和插入的场景。
multiset和unordered_multiset允许元素重复,适用于需要存储相同键的场景。
unordered_set和unordered_multiset在插入和查找操作上通常比set和multiset更快,但它们没有保持元素的有序性。
三.pair二元组
1.简介
在C++的STL(Standard Template Library)中,pair是一个非常有用的模板类。它提供了一种简单的方式来存储一对值,即键值对。pair可以用于各种场景,例如在容器中存储关联的数据,返回多个值等。本文将详细介绍C++ STL中pair的使用方法和一些常见操作。
2.包含头文件及其初始化
(1)头文件
#include <utility>
(2)初始化
pair<Type1, Type2> myPair; // 声明一个空的pair
pair<Type1, Type2> myPair(value1, value2); // 使用给定的值初始化pair
myPair = std::make_pair(value1, value2); // 使用make_pair函数创建pair并赋值
3.访问与修改
//定义结构体数组
pair<int,int>p[20];
for(int i = 0; i < 20; i++)
{//和结构体类似,first代表第一个元素,second代表第二个元素cout << p[i].first << " " << p[i].second;
}
pair可以作为容器(例如vector、list、map等)的元素使用。这样可以方便地存储和访问关联的数据。
下面是一个使用pair作为容器元素的示例代码:
int main() {vector<pair<int, string>> myVector;// 添加pair元素myVector.push_back(make_pair(1, "Alice"));myVector.push_back(make_pair(2, "Bob"));myVector.push_back(make_pair(3, "Charlie"));// 遍历输出pair元素for (const auto& pair : myVector) {cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;}return 0;
}
在上述示例代码中,我们创建了一个vector容器myVector,其中的元素是pair类型,包含一个整数和一个字符串。
然后,我们使用push_back()函数向容器中添加了一些pair元素。
最后,我们使用范围遍历来输出容器中的pair元素。
相关文章:

【C++ STL之map,set,pair详解】
目录 一.map映射1.简介2.包含头文件及其初始化3.基本操作4.用迭代器正反遍历5.添加元素的四种方式6.元素的访问7.对比unordered_map,multimap 二.set集合1.简介2.包含头文件及其初始化3.基本操作4.元素的访问5.set,multiset,unordered_set&am…...

Python LEGB规则解析与应用
引言 推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 http…...

气象监测站:用科技感知气象变化
气象监测站是利用科学技术感知当地小气候变化情况的气象观测仪器,可用于农业、林业、养殖业、畜牧业、环境保护、工业等多个领域,提高对环境数据的利用率,促进产业效能不断提升。 气象监测站主要由气象传感器、数据传输系统、电源系统、支架…...

Linux debian12解压和压缩.rar文件教程
一、Debian12安装rar命令 sudo apt install rar二、使用rar软件 1.解压文件 命令格式: rar x 文件名.rar实例测试: [rootdoudou tmp]# rar x test.rar2.压缩文件 test是一个文件夹 命令格式: rar a 文件名.rar 文件夹名实例测试&#x…...

探析国际大文件传输的花费与降低开销的小妙招
随着全球化的不断发展,跨国企业日益增多,因此国外大文件传输也日益普遍。在这种背景下,国外大文件传输方式的需求也相应增加。本文旨在深入分析国外大文件传输的成本,并提出有效降低这些成本的方法。 一、国外大文件传输成本分析 …...

Linux中shell脚本——for、while循环及脚本练习
目录 一.for循环 1.1.基本格式 1.2.类C语言格式 二.while循环 2.1.基本格式 2.2.死循环语句 三.跳出循环 3.1.continue跳出循环 3.2.break跳出循环 四.常用循环 4.1.循环打印九九乘法表 4.2.循环ping测试某个网段网络连通性 4.3.while死循环实现猜数字游戏 4.4.数…...

【数字实验室】时钟切换
大部分开发者使用 BUFGCTRL 或 BUFGMUX进行时钟切换,它们在时钟切换上可以提供无毛刺输出。然而,了解所涉及的原理是有好处的。 当然,无论我们在同步逻辑中使用哪种技术,重要的是要确保在进行时钟切换时输出上没有毛刺。任何故障都…...

线性代数的学习和整理7:各种特殊效果矩阵特例(草稿-----未完成)
目录 1 矩阵 1.1 1维的矩阵 1.2 2维的矩阵 1.3 没有3维的矩阵---3维的是3阶张量 2 方阵 3 单位矩阵 3.1 单位矩阵的定义 3.2 单位矩阵的特性 3.3 为什么单位矩阵I是 [1,0;0,1] 而不是[0,1;1,0] 或[1,1;1,1] 3.4 零矩阵 3.4 看下这个矩阵 [0,1;1,0] 3.5 看下这个矩阵…...

springBoot 配置文件 spring.mvc.throw-exception-if-no-handler-found 参数的作用
在Spring Boot应用中,可以通过配置文件来控制当找不到请求处理器(handler)时是否抛出异常。具体的配置参数是spring.mvc.throw-exception-if-no-handler-found。 默认情况下,该参数的值为false,即当找不到请求处理器时…...

linux部署kafka3.5.1(单机)
一、下载jdk17 kafka3.x版本需要jdk11以上版本才能更好的兼容,jdk11、jdk17都是LTS长期维护版本,而且jdk17支持springboot3.x,所以我选择了openjdk17。 下载地址: Archived OpenJDK GA Releaseshttps://jdk.java.net/archive/ 二、上传jdk安装包解压 …...

css 实现svg动态图标效果
效果演示: 实现思路:主要是通过css的stroke相关属性来设置实现的。 html代码: <svgt"1692441666814"class"icon"viewBox"0 0 1024 1024"version"1.1"xmlns"http://www.w3.org/2000/svg"p-id"…...

软件测试项目实战,电商业务功能测试点汇总(全覆盖)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 支付功能怎么测试…...

LeetCode[274]H指数
难度:Medium 题目: 给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指…...

MyBatis-Plus快速开始[MyBatis-Plus系列] - 第482篇
悟纤:师傅,MyBatis-Plus被你介绍的这么神乎其乎,咱们还是来的点实际的吧。 师傅:那真是必须的,学习技术常用的一种方法,就是实践。 悟纤:贱贱更健康。 师傅:这… 师傅:…...

CF1003A Polycarp‘s Pockets 题解
题目传送门 题目意思: 给你 n n n 个数,求出最多相同的数的个数。 这道题目有两种解法。 方法一:桶排 一边输入,一边将第 i i i 个数 a i a_i ai 出现的次数存在一个数组 b b b 的第 a i a_i ai 个位置。输入完后遍历…...

数据库厂商智臾科技加入龙蜥社区,打造多样化的数据底座
近日,浙江智臾科技有限公司(以下简称“智臾科技”)正式签署 CLA 贡献者许可协议,加入龙蜥社区(OpenAnolis)。 智臾科技主创团队从 2012 年开始投入研发 DolphinDB。DolphinDB 作为一款基于高性能时序数据库…...

一天赚四五十的副业,可以试试这几种
大家都希望能够有额外的零花钱,尤其是对于学生和不收入稳定的人来说。今天,我将分享一些简单实用的赚钱技巧,帮助你每天赚取四五十的零花钱,让你的钱包更丰盈。 第一种:蚂蚁路客和友活来了 支付宝旗下两款接任务拍门…...

OpenCV 中的色彩空间 (C++ / Python)
在本教程中,我们将了解计算机视觉中使用的流行色彩空间,并将其用于基于颜色的分割。我们还将分享 C++ 和 Python 的演示代码。...

邀请函 | 高质量区块链·元宇宙—标准行系列沙龙(北京站)即将开启
区块链、元宇宙是近年来备受关注的新兴技术,也是推动数字经济发展的重要力量。高质量标准引领高质量发展,加快形成标准引领,充分释放区块链、元宇宙对实体经济牵引赋能效应,推进形成相关产业体系高质量发展新格局刻不容缓。 为进…...

php hmacsha256加密的算法
HMAC-SHA256是一种基于哈希算法的消息认证码算法,用于验证数据的完整性和真实性。它将密钥和数据一起进行哈希运算,生成一个固定长度的摘要值。只有知道密钥的人才能够验证该摘要值的真实性。 在PHP中,可以使用hash_hmac函数来计算HMAC-SHA2…...

Spring源码编译教程
1. Spring版本是5.3.10 2. 下载gradle依赖 Spring是通过gradle来编译源码下载依赖的,.gradle文件夹可以理解为gradle的仓库(和mave类似,不懂gradle的先这么理解),而我给大家的这个仓库,只包含了Spring源码…...

Python入门教程 | Python简介和环境搭建
Python 简介 Python是一种高级编程语言,由荷兰人Guido van Rossum于1991年创建。它以其简单易学、可读性强和丰富的生态系统而受到广泛喜爱。它被广泛应用于各个领域,包括Web开发、科学计算、数据分析、人工智能等。 Python的特点 简洁易读:…...

阿里云ECS服务器企业级和共享型介绍_企业级常见问题解答FAQ
阿里云企业级服务器是什么?企业级和共享型有什么区别?企业级服务器具有独享且稳定的计算、存储、网络资源,如ECS计算型c6、通用型g8等都是企业级实例,阿里云百科分享什么是企业级云服务器、企业级实例的优势、企业级和共享型云服务…...

leetcode做题笔记92. 反转链表 II
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 示例 1: 思路一:头插法 struct ListNode *reverseBetween(struct ListNode *h…...

springboot引入druid解析sql
一、前言 在开发中,有时我们可能会需要获取SQL中的表名,那么因为不同的数据源类型SQL会存在部分差异,那么我们就可以使用alibaba 的druid包实现不同的数据源类型的sql解析。 二、引入相关maven依赖 <dependency><groupId>com.a…...

学习笔记十九:Pod常见的状态和重启策略
Pod常见的状态和重启策略 常见的pod状态第一阶段:第二阶段:扩展: pod重启策略测试Always重启策略正常停止容器内的tomcat服务非正常停止容器里的tomcat服务 测试never重启策略正常停止容器里的tomcat服务非正常停止容器里的tomcat服务 测试On…...

Spring的ApplicationEvent简单使用
ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。事件发布者并不需要考虑谁去监听,监听具体的实现…...

python程序员面试题之:set vs tuple vs list vs dict
首先,set/tuple/list/dict都是存储变量的python类型,四者之间有异有同。 首先,set存储无序不重复序列。 set_b {1,2,4} print(set_b[0]) TypeError: ‘set’ object is not subscriptable set 会自动去重,所以根据这个特性可以对…...

STM32 F103C8T6学习笔记11:RTC实时时钟—OLED手表日历
之前在 学习笔记10文章 做了一个简易的,使用定时器计时的简单时钟,现在使用RTC实时时钟同步代替定时器来实现一下OLED手表日历,接着上个实验文章进行完善~~ 文章提供源码、测试工程下载、测试效果图。 目录 RTC实时时钟: 简介&…...

无法将“环境变量”项识别为 cmdlet、函数、脚本文件或可运行程序的名称(pycharm)
无法将“配置的任何一个环境变量”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 记录解决“无法将“C:......conda.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称”以及“表达式或语句中包含意外的标记”的系列问题(VSCode开发环境)一、Conda.exe无法正常识…...