当前位置: 首页 > news >正文

c++STL——map与set的使用及介绍

目录

前言:

1. 关联式容器

2. 键值对

3. 树形结构的关联式容器 

3.1 set

3.1.1 set的介绍

3.1.2 set的使用

1. set的模板参数列表

2. set的构造

3. set的迭代器 

4. set的容量 

5. set修改操作 

 6. set的使用举例

 3.2 map

3.2.1 map的介绍

3.2.2 map的使用

1. map的模板参数说明

​编辑

2.map的构造

3.map的迭代器

4. map的容量与元素访问 

5. map中元素的修改 

3.3 multiset 

3.3.1 multiset的介绍

3.3.2 multiset的使用

3.4 multimap 

3.4.1 multimap的介绍

3.4.2 multimap的使用


前言:

  在上一期博客中,我们介绍了二叉搜索树的结构及使用,也了解到了二叉搜索树的结构虽然在大部分情况下搜索的速度非常快,但是它的时间复杂度最终还是由数据的插入顺序决定,所以我们要学习另一种结构——平衡二叉树,平衡二叉树的本质还是二叉搜索树,但是它解决了二叉搜索树时间复杂度由插入顺序决定的问题,所以它的时间复杂度达到了log(N),对于这样一种高效的数据结构是不是得掌握它呢。

1. 关联式容器

    在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、
forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面
存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?

    关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的
键值对,在数据检索时比序列式容器效率更高

2. 键值对

    用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代
表键值,value表示与key对应的信息
。比如:现在要建立一个英汉互译的字典,那该字典中必然
有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应
该单词,在词典中就可以找到与其对应的中文含义。

SGI-STL中关于键值对的定义:

template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(): first(T1()), second(T2())
{}
pair(const T1& a, const T2& b): first(a), second(b)
{}
};

3. 树形结构的关联式容器 

    根据应用场景的不同,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。下面一依次介绍每一个容器。简单介绍一下map就是key_value结构,有两个参数,适用于建立词典这种操作,例如我们要插入一个单词”first“,就需要将它的中文和英文意思插入到map结构中,map的两个参数分别代表单词的中英文意思。set则与map差别不大,但是set是key结构,只有一个参数,所以我们存储单个数据时可以使用set。值得注意的是:map与set都不允许冗余(在容器中存入相同的数据)。而multimap,mulitset与map,set的区别就是它们允许冗余。

3.1 set

3.1.1 set的介绍

我们来看文档中关于set的介绍:

翻译:

1. set是按照一定次序存储元素的容器
2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。
set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行
排序。
4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对
子集进行直接迭代。
5. set在底层是用二叉搜索树(红黑树)实现的。 

3.1.2 set的使用

1. set的模板参数列表

T: set中存放元素的类型,实际在底层存储<value, value>的键值对。
Compare:set中元素默认按照小于来比较
Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理 

2. set的构造

3. set的迭代器 

4. set的容量 

5. set修改操作 

 6. set的使用举例
#include <set>
void TestSet()
{// 用数组array中的元素构造setint array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4,
6, 8, 0 };
set<int> s(array, array+sizeof(array)/sizeof(array[0]));
cout << s.size() << endl;
// 正向打印set中的元素,从打印结果中可以看出:set可去重
for (auto& e : s)
cout << e << " ";
cout << endl;
// 使用迭代器逆向打印set中的元素
for (auto it = s.rbegin(); it != s.rend(); ++it)
cout << *it << " ";
cout << endl;
// set中值为3的元素出现了几次
cout << s.count(3) << endl;
}

      由于set的使用与我们之前学过的其他容器的使用相似,所以我们不过多介绍, 在这个阶段我们更多关注的应该是知识本身。

 3.2 map


3.2.1 map的介绍

下面是文档中关于map的介绍:

翻译:

1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元
素。
2. 在map中,键值key通常用于排序和唯一地标识元素,而值value中存储与此键值key关联
的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类
型value_type绑定在一起,为其取别名称为pair:
typedef pair<const key, T> value_type;
3. 在内部,map中的元素总是按照键值key进行比较排序的。
4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序
对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

3.2.2 map的使用

1. map的模板参数说明

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

2.map的构造

3.map的迭代器

4. map的容量与元素访问 

问题:当key不在map中时,通过operator获取对应value时会发生什么问题?

 翻译:

     注意:在元素访问时,有一个与operator[]类似的操作at()(该函数不常用)函数,都是通过
key找到与key对应的value然后返回其引用,不同的是:当key不存在时,operator[]用默认
value与key构造键值对然后插入,返回该默认value,at()函数直接抛异常。

5. map中元素的修改 

#include <string>
#include <map>
void TestMap()
{
map<string, string> m;
// 向map中插入元素的方式:
// 将键值对<"peach","桃子">插入map中,用pair直接来构造键值对
m.insert(pair<string, string>("peach", "桃子"));
// 将键值对<"peach","桃子">插入map中,用make_pair函数来构造键值对
m.insert(make_pair("banan", "香蕉"));
// 借用operator[]向map中插入元素/*
operator[]的原理是:用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器operator[]函数最后将insert返回值键值对中的value返回
*/// 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引
用结果,
m["apple"] = "苹果";
// key不存在时抛异常
//m.at("waterme") = "水蜜桃";
cout << m.size() << endl;
// 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列
for (auto& e : m)
cout << e.first << "--->" << e.second << endl;
cout << endl;
// map中的键值对key一定是唯一的,如果key存在将插入失败
auto ret = m.insert(make_pair("peach", "桃色"));
if (ret.second)
cout << "<peach, 桃色>不在map中, 已经插入" << endl;
else
cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
<< ret.first->second <<" 插入失败"<< endl;
// 删除key为"apple"的元素
m.erase("apple");
if (1 == m.count("apple"))
cout << "apple还在" << endl;
else
cout << "apple被吃了" << endl;
}

【总结】

1. map中的的元素是键值对
2. map中的key是唯一的,并且不能修改
3. 默认按照小于的方式对key进行比较
4. map中的元素如果用迭代器去遍历,可以得到一个有序的序列
5. map的底层为平衡搜索树(红黑树),查找效率比较高:O(log_2 N)
6. 支持[]操作符,operator[]中实际进行插入查找。

3.3 multiset 

3.3.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底层结构为二叉搜索树(红黑树)。

注意:
1. multiset中在底层中存储的是<value, value>的键值对
2. multiset的插入接口中只需要插入即可
3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的
4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列
5. multiset中的元素不能修改
6. 在multiset中找某个元素,时间复杂度为$O(log_2 N)$
7. multiset的作用:可以对元素进行排序

3.3.2 multiset的使用

此处只简单演示set与multiset的不同,其他接口接口与set相同,同学们可参考set。

#include <set>
void TestSet()
{int array[] = { 2, 1, 3, 9, 6, 0, 5, 8, 4, 7 };
// 注意:multiset在底层实际存储的是<int, int>的键值对
multiset<int> s(array, array + sizeof(array)/sizeof(array[0]));
for (auto& e : s)
cout << e << " ";
cout << endl;
return 0;
}

3.4 multimap 

3.4.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在底层用二叉搜索树(红黑树)来实现。

注意:multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以
重复的
。 

3.4.2 multimap的使用

multimap中的接口可以参考map,功能都是类似的。
注意:
1. multimap中的key是可以重复的。
2. multimap中的元素默认将key按照小于来比较
3. multimap中没有重载operator[]操作(同学们可思考下为什么?)。
4. 使用时与map包含的头文件相同。

本章完。

相关文章:

c++STL——map与set的使用及介绍

目录 前言&#xff1a; 1. 关联式容器 2. 键值对 3. 树形结构的关联式容器 3.1 set 3.1.1 set的介绍 3.1.2 set的使用 1. set的模板参数列表 2. set的构造 3. set的迭代器 4. set的容量 5. set修改操作 6. set的使用举例 3.2 map 3.2.1 map的介绍 3.2.2 map的…...

Vxe UI vue vxe-table select 下拉框选项列表数据量超大过大时卡顿解决方法

Vxe UI vue vxe-table vxe-grid select 下拉框选项列表数据量超大过大时卡顿解决方法 查看 github vxe-table 官网 vxe-table 本身支持虚拟滚动&#xff0c;数据量大也是支持的&#xff0c;但是如果在可编辑表格中使用下拉框&#xff0c;下拉框的数据量超大时&#xff0c;可能…...

python 基础笔记(其实有点内容的)

print(math.gamma(n)) # 求 (n-1) 的阶乘 数值, 数值计算 format(50, “b”) bin(50)[2:]&#xff0c; 这个“b” 就代表的是 binary format(14, ‘b’) ------> ‘1110’ 去除 0b 去掉前导零 str(000001) # 只适合python2.x ‘1’ “00000001”.lstrip(“0”) # python3…...

(39)MATLAB生成高斯脉冲及其频谱

文章目录 前言一、MATLAB仿真代码二、仿真结果画图 前言 高斯脉冲在通信中是很重要的调制符号波形&#xff0c;本文使用MATLAB生成高斯脉冲&#xff0c;并使用FFT变换给出其频谱。 一、MATLAB仿真代码 代码如下&#xff1a; % 信号参数 fs 100; % 采样…...

35岁前端开发者:转型还是坚守?

在互联网行业&#xff0c;35岁似乎成了一个敏感的年龄分水岭。很多前端开发者开始思考&#xff1a;到了35岁&#xff0c;是不是都要转型&#xff1f;本文将探讨这个话题&#xff0c;希望能为面临这一困惑的前端开发者提供一些参考。 一、35岁焦虑&#xff1a;现实还是误解&…...

对MVC详细解读

一、MVC模式的详细组成部分 1. 模型&#xff08;Model&#xff09; 数据结构&#xff1a; 模型通常使用类或结构来定义应用程序的数据结构。例如&#xff0c;在Ruby on Rails中&#xff0c;模型通常与数据库表相对应&#xff0c;使用Active Record模式。 数据访问层&#xff1…...

centos系列图形化 VNC server配置,及VNC viewer连接,2024年亲测有效

centos系列图形化 VNC server配置&#xff0c;及VNC viewer连接 0.VNC服务介绍 VNC英文全称为Virtual Network Computing&#xff0c;可以位操作系统提供图形接口连接方式&#xff0c;简单的来说就是一款桌面共享应用&#xff0c;类似于qq的远程连接。该服务是基于C/S模型的。…...

STL序列式容器之string的基本用法及实现

1.string类 在使用string类时&#xff0c;必须包含<string>头文件以及using namespace std&#xff1b; 接下来我们看看string类是如何被声明的&#xff1a; typedef basic_string<char> string; 可以看到&#xff1a;string类是被类模板basic_string用数据类型…...

lua脚本使用cjson转换json时,空数组[]变成了空对象{}

一、前言 项目lua使用工具&#xff1a;cjson 问题&#xff1a;reids中部分数据的json key存在为[]的值&#xff0c;使用cjson进行解析的时候将原本空数组[]解析成了空对象{} 目标&#xff1a;原本[] 转 [] 二、解决方案 在使用cjson类库时&#xff0c;先配置json转换要求 -…...

ImportError: /../lib/libstdc++.so.6: version `GLIBCXX_3.4.29解决方案

今天跑实验遇到了一个头疼的报错&#xff0c;完全看不懂&#xff0c;上网查了一下成功解决&#xff0c;但是网上的指令没法直接拿来用&#xff0c;所以在这里记录一下自己的解决方案。 报错信息&#xff1a; Traceback (most recent call last):File "/home/shizhiyuan/c…...

java-实现一个简单的httpserver-0.6.0

2024年10月14日14:17:07—0.6.0 java-实现一个简单的httpserver-0.6.0 背景功能具体代码打印 背景 通常写了一些接口&#xff0c;需要通过临时的http访问&#xff0c;又不需要spring这么厚重的框架 功能 设置并发监控并发两个get请求一个是根路径&#xff0c;一个是other增加…...

【论文#码率控制】ADAPTIVE RATE CONTROL FOR H.264

目录 摘要1.前言2.基本知识2.1 蛋鸡悖论2.2 基本单元的定义2.3 线性MAD预测模型 3.GOP级码率控制3.1 总比特数3.2 初始化量化参数 4.帧级码率控制4.1 非存储图像的量化参数4.2 存储图像的目标比特 5.基本单元级码率控制6.实验结果7.结论 《ADAPTIVE RATE CONTROL FOR H.264》 A…...

2024-10-16 学习人工智能的Day8

函数 定义&#xff08;创建&#xff09; 函数的创建def开始&#xff0c;后接函数名&#xff0c;在给参数表最后冒号表示函数基础信息给定 换行书写函数内部定义&#xff0c;在函数内部定义操作&#xff0c;最后函数自带返回&#xff0c;无定义返回值返回为None&…...

Python Django 数据库优化与性能调优

Python Django 数据库优化与性能调优 Django 是一个非常流行的 Python Web 框架&#xff0c;它的 ORM&#xff08;对象关系映射&#xff09;允许开发者以简单且直观的方式操作数据库。然而&#xff0c;随着数据量的增长&#xff0c;数据库操作的效率可能会成为瓶颈&#xff0c…...

基于SpringBoot+微信小程序的农产品销售平台

基于SpringBoot微信小程序的农产品销售平台 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目…...

微前端学习以及分享

微前端学习以及分享 注&#xff1a;本次分享demo的源码github地址&#xff1a;https://github.com/rondout/micro-frontend 什么是微前端 微前端的概念是由ThoughtWorks在2016年提出的&#xff0c;它借鉴了微服务的架构理念&#xff0c;核心在于将一个庞大的前端应用拆分成多…...

【Linux-进程间通信】vscode使用通信引入匿名管道引入

一、新系统&#xff0c;新软件 1.新系统 哈喽宝子们&#xff0c;从今以后我们不再使用风靡一时的CentOS系统了&#xff0c;因为CentOS已经不在维护了&#xff0c;各大公司几乎也都从CentOS转入其他操作系统了&#xff1b;我们现在由原来的CentOS系统切换到最新的Ubuntu系统&a…...

nerd bug:VPG多次计算vnetloss的计算图报错的解决

待更 Reference https://www.cnblogs.com/StarZhai/p/15495292.htmlhttps://github.com/huggingface/transformers/issues/12613https://discuss.pytorch.org/t/inplace-operation-errors-when-implementing-a2c-algorithm/145406/6...

BigDecimal类Date类JDK8日期

一、BigDecimal类是什么&#xff1f;它有什么用&#xff1f;先看一段代码&#xff0c;看这个代码有什么问题再说BigDeimal这个类是干什么用的&#xff0c;这样会好理解一些。 public class Test {public static void main(String[] args) {System.out.println(0.1 0.2);Syste…...

MybatisWebApp

如何构建一个有关Mybatis的Web&#xff1f; 在这里给出我自己的一些配置。我的TomCat版本&#xff1a;10.1.28 &#xff0c;IDEA版本&#xff1a;2024.1.4 Pom.XML文件 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/200…...

FPGA时序优化实战:如何用Path Group提升关键路径性能(附PrimeTime配置)

FPGA时序优化实战&#xff1a;如何用Path Group提升关键路径性能&#xff08;附PrimeTime配置&#xff09; 在FPGA设计流程中&#xff0c;时序收敛往往是工程师面临的最大挑战之一。当设计规模达到数百万门级别时&#xff0c;传统的全局优化方法常常会导致关键路径被非关键路径…...

通过爱毕业AI的智能改写功能,五个方法助你快速降低论文重复率

嘿&#xff0c;大家好&#xff01;我是AI菌。今天咱们来聊聊一个让无数学生头疼的问题&#xff1a;论文重复率飙到30%以上怎么办&#xff1f;别慌&#xff0c;我这就分享5个实用降重技巧&#xff0c;帮你一次搞定&#xff0c;轻松压到合格线以下。这些方法都是我亲身试验过的&a…...

中关村论坛重磅发布十五项脑机接口成果

当前&#xff0c;脑机接口技术正处于从实验室走向临床应用、从技术突破迈向产业转化的关键时期。中关村论坛重磅发布十五项脑机接口创新成果&#xff0c;聚焦学术创新性、产品合规性、临床突破性与生态共建性四大核心维度&#xff0c;集中呈现我国在该领域的前沿进展。本次发布…...

NeoPixel Painter:嵌入式HSV动画的固定点实现

1. NeoPixel Painter 库概述NeoPixel Painter 是一个面向嵌入式 LED 动画开发的轻量级 Arduino 库&#xff0c;专为简化 WS2812B&#xff08;NeoPixel&#xff09;LED 灯带的动态效果编程而设计。它并非对 Adafruit_NeoPixel 库的简单封装&#xff0c;而是构建在其之上的状态驱…...

iOS证书(.p12)和描述文件生成避坑指南:从App ID创建到真机测试UDID添加

iOS证书与描述文件生成全流程解析&#xff1a;从核心概念到实战避坑 第一次接触iOS应用打包的开发者&#xff0c;往往会在证书和描述文件这一关卡住。明明按照教程一步步操作&#xff0c;却总是遇到各种报错——"证书无效"、"描述文件不匹配"、"设备未…...

规则直观落地操作指南(零理解成本・照做就生效・效果肉眼可见)

规则直观落地操作指南(零理解成本・照做就生效・效果肉眼可见) 核心原则:所有内容全是「动作指令」,无概念、无术语、无废话;每一步操作都有「即时可验证的落地效果」,不用等项目结束,做完立刻知道有没有用。 一、先锁死 3 条零理解成本操作铁律(必须先遵守,否则所有…...

别再傻傻下载Gurobi软件了!Anaconda虚拟环境里一条conda命令搞定学术版安装(Win11实测)

颠覆认知的Gurobi安装指南&#xff1a;一条conda命令解锁学术版完整功能 每次看到同行们花半小时下载几个GB的Gurobi安装包&#xff0c;我就忍不住想分享这个被多数人忽略的高效方案。作为在运筹优化领域深耕多年的研究者&#xff0c;我发现90%的学术用户根本不需要走传统安装…...

Win11环境实测:用C# EtherCAT库控制伺服电机,从TwinCAT配置到pcap抓包全流程避坑

Win11环境下的EtherCAT实战&#xff1a;C#控制伺服电机全流程解析 在工业自动化领域&#xff0c;EtherCAT凭借其高速、实时的特性已成为运动控制系统的首选协议之一。本文将带你深入Windows 11环境下使用C#开发EtherCAT主站的全过程&#xff0c;从TwinCAT配置到实际控制伺服电机…...

【水果分类】基于GUI计算机视觉和前馈神经网络自动水果分类系统附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…...

2025年具身智能创业指南:从芯片选型到场景落地的完整避坑手册

2025年具身智能创业指南&#xff1a;从芯片选型到场景落地的完整避坑手册 当波士顿动力的Atlas机器人完成一套流畅的后空翻动作时&#xff0c;全世界都意识到——具身智能的时代已经到来。2025年的今天&#xff0c;具身智能正从实验室走向产业化&#xff0c;创业者们面临的不再…...