【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元素。

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

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

相关文章

为什么需要单元测试?

为什么需要单元测试&#xff1f; 从产品角度而言&#xff0c;常规的功能测试、系统测试都是站在产品局部或全局功能进行测试&#xff0c;能够很好地与用户的需要相结合&#xff0c;但是缺乏了对产品研发细节&#xff08;特别是代码细节的理解&#xff09;。 从测试人员角度而言…

Qt应用开发(基础篇)——纯文本编辑窗口 QPlainTextEdit

一、前言 QPlainTextEdit类继承于QAbstractScrollArea&#xff0c;QAbstractScrollArea继承于QFrame&#xff0c;是Qt用来显示和编辑纯文本的窗口。 滚屏区域基类https://blog.csdn.net/u014491932/article/details/132245486?spm1001.2014.3001.5501框架类QFramehttps://blo…

Elasticsearch复合查询之Boosting Query

前言 ES 里面有 5 种复合查询&#xff0c;分别是&#xff1a; Boolean QueryBoosting QueryConstant Score QueryDisjunction Max QueryFunction Score Query Boolean Query在之前已经介绍过了&#xff0c;今天来看一下 Boosting Query 用法&#xff0c;其实也非常简单&…

Chapter 15: Object-Oriented Programming | Python for Everybody 讲义笔记_En

文章目录 Python for Everybody课程简介Object-oriented programmingManaging larger programsGetting startedUsing objectsStarting with programsSubdividing a problemOur first Python objectClasses as typesObject lifecycleMultiple instancesInheritanceSummaryGlossa…

[.NET学习笔记] -.NET6.0项目动态加载netstandard2.0报错但项目添加引用则正常的问题

问题描述 .NET6.0的项目使用netstandard2.0版本的动态链接库。若是在项目中直接添加引用&#xff0c;应用netstandard2.0项目或者netstandard2.0编译后的dll均能正常工作。但如果通过xcopy等方式&#xff0c;额外将对应的dll复制到执行目录&#xff0c;会执行失败。调用方式一…

python基础5——正则、数据库操作

文章目录 一、数据库编程1.1 connect()函数1.2 命令参数1.3 常用语句 二、正则表达式2.1 匹配方式2.2 字符匹配2.3 数量匹配2.4 边界匹配2.5 分组匹配2.6 贪婪模式&非贪婪模式2.7 标志位 一、数据库编程 可以使用python脚本对数据库进行操作&#xff0c;比如获取数据库数据…

Docker 搭建 LNMP + Wordpress(详细步骤)

目录 一、项目模拟 1. 项目环境 2. 服务器环境 3.任务需求 二、Linux 系统基础镜像 三、Nginx 1. 建立工作目录 2. 编写 Dockerfile 脚本 3. 准备 nginx.conf 配置文件 4. 生成镜像 5. 创建自定义网络 6. 启动镜像容器 7. 验证 nginx 四、Mysql 1.…

申请部署阿里云SSL免费证书

使用宝塔自动创建的证书有时候会报NET::ERR_CERT_COMMON_NAME_INVALID&#xff0c;并且每次只能三个月&#xff0c;需要点击续期非常麻烦&#xff0c;容易遗忘。 阿里云免费SSL证书 前往阿里云管理控制台【数字证书管理服务】【SSL证书】&#xff0c;每年20个额度&#xff0c;一…

标签准备——labelIMG工具使用——自动化标注

在实际生产项目中,为了提升目标识别的准确性,我们往往需要3000-5000张图片进行标注。而直接参与过标注的人都有一个共同的感觉,就是标注是一个简单、枯燥、无聊且十分耗时费力的差事。为此,我们可以在有了初步训练模型的基础上,采用更加自动化的方式进行标注,届时,你讲不…

springBoot 配置文件 flyway 插件相关参数说明

在Spring Boot应用中使用Flyway插件进行数据库迁移时&#xff0c;可以在应用的配置文件中配置相关参数。下面是常用的Flyway配置参数及其说明&#xff1a; flyway.enabled: 是否启用Flyway插件&#xff0c;默认为true&#xff0c;表示启用Flyway插件进行数据库迁移。flyway.ur…

基于Pytorch构建DenseNet网络对cifar-10进行分类

DenseNet是指Densely connected convolutional networks&#xff08;密集卷积网络&#xff09;。它的优点主要包括有效缓解梯度消失、特征传递更加有效、计算量更小、参数量更小、性能比ResNet更好。它的缺点主要是较大的内存占用。 DenseNet网络与Resnet、GoogleNet类似&#…

QChart:数据可视化(用图像形式显示数据内容)

1、数据可视化的图形有&#xff1a;柱状/线状/条形/面积/饼/点图、仪表盘、走势图&#xff0c;弦图、金字塔、预测曲线图、关系图、数学公式图、行政地图、GIS地图等。 2、在QT Creator的主页面&#xff0c;点击 欢迎》示例》右侧输入框 输入Chart&#xff0c;即可查看到QChar…

go es实例

go es实例 1、下载第三方库 go get github.com/olivere/elastic下载过程中出现如下报错&#xff1a; 解决方案&#xff1a; 2、示例 import package mainimport ("context""encoding/json""fmt""reflect""time""…

LabVIEW模拟化学反应器的工作

LabVIEW模拟化学反应器的工作 近年来&#xff0c;化学反应器在化学和工业过程领域有许多应用。高价值产品是通过混合产品&#xff0c;化学反应&#xff0c;蒸馏和结晶等多种工业过程转换原材料制成的。化学反应器通常用于大型加工行业&#xff0c;例如酿酒厂公司饮料产品的发酵…

微信小程序中如何动态添加 class 属性

在微信小程序中&#xff0c;你可以使用setData方法来动态添加class。首先&#xff0c;在你的页面的js文件中&#xff0c;定义一个变量来存储需要动态添加的class&#xff0c;例如&#xff1a; data: {dynamicClass: }然后&#xff0c;在需要动态添加class的地方&#xff0c;使…

list元素

列表元素 列表元素分为有序列表和无序列表 有序列表 ol – order list – 有序列表 li – list item – 列表元素 <ol type"1"><li>有序列表1</li><li>有序列表2</li><li>有序列表3</li> </ol>属性 type type属…

提示词4大经典框架;将AI融入动画工作流的案例和实践经验;构建基于LLM的系统和产品的模式;提示工程的艺术 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 高效提示词的4大经典框架&#xff1a;ICIO、CRISPE、BROKE、RASCEF ICIO 框架 Intruction (任务) &#xff1a;你希望AI去做的任务&am…

2023年目标检测研究进展

综述 首先关于写这个笔记&#xff0c;我个人思考了很久关于以下几点。1&#xff1a;19年开始从做OCR用到图像和文本这种多模态联合处理的后&#xff0c;也就有意识的开始关注自然语言处理&#xff0c;这样的结果导致可能停留在前期图像上的学习和实践&#xff0c;停滞的研究如…

微服务中间件--Ribbon负载均衡

Ribbon负载均衡 a.Ribbon负载均衡原理b.Ribbon负载均衡策略 (IRule)c.Ribbon的饥饿加载 a.Ribbon负载均衡原理 1.发起请求http://userservice/user/1&#xff0c;Ribbon拦截该请求 2.Ribbon通过EurekaServer拉取userservice 3.EurekaServer返回服务列表给Ribbon做负载均衡 …

bug记录:微信小程序 给button使用all: initial重置样式

场景&#xff1a;通过uniapp开发微信小程序 &#xff0c;使用uview的u-popup弹窗&#xff0c;里面内嵌了一个原生button标签&#xff0c;因为微信小程序的button是有默认样式的&#xff0c;所以通过all: initial重置样式 。但是整个弹窗的点击事件都会被button上面的点击事件覆…