【C++】map和set的使用
map和set
- 一、set
- 1.1 set的介绍
- 1.2 set的使用
- 1.2.1 set的构造
- 1.2.2 set的迭代器
- 1.2.3 set的修改
- 1.2.3.1 insert && find && erase
- 1.2.3.2 count
- 1.3 multiset
- 二、map
- 2.1 map的介绍
- 2.2 map的使用
- 2.2.1 map的修改
- 2.2.1.1 insert
- 2.2.1.2 统计次数
- 2.3 multimap
一、set
1.1 set的介绍

首先要知道set的底层是由红黑树(平衡二叉搜索树)实现的。
Tset存放元素类型,底层是<value, value>的键值对。
Compare仿函数,因为实现搜索树需要比较。
1.2 set的使用
1.2.1 set的构造
void test_set()
{// 默认构造set<int> s1;// 迭代器区间构造int a[] = { 1, 2, 3, 4 };set<int> s2(a, a + 4);// 拷贝构造(深拷贝)set<int> s3(s2);for (int e : s2) cout << e << " ";cout << endl;for (int e : s3) cout << e << " ";cout << endl;
}

1.2.2 set的迭代器

可以看到set有反向迭代器。
void test1()
{set<int> s;// 排序+去重s.insert(1);s.insert(2);s.insert(3);s.insert(1);s.insert(3);s.insert(4);// 正向迭代器set<int>::iterator it1 = s.begin();while (it1 != s.end()){cout << *it1++ << " ";}cout << endl;// 反向迭代器set<int>::reverse_iterator it2 = s.rbegin();while (it2 != s.rend()){cout << *it2++ << " ";}cout << endl;
}

因为set的仿函数默认参数是less<T>,所以排的是升序,如果我们想排降序就可以传递greater<T>。
void test1()
{set<int, greater<int>> s;// 排序+去重s.insert(1);s.insert(2);s.insert(3);s.insert(1);s.insert(3);s.insert(4);// 正向迭代器set<int>::iterator it1 = s.begin();while (it1 != s.end()){cout << *it1++ << " ";}cout << endl;// 反向迭代器set<int>::reverse_iterator it2 = s.rbegin();while (it2 != s.rend()){cout << *it2++ << " ";}cout << endl;
}

1.2.3 set的修改
1.2.3.1 insert && find && erase



void test2()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);set<int>::iterator it = s.find(3);s.erase(it);for (auto& e : s){cout << e << " ";}cout << endl;
}

1.2.3.2 count

传进去一个元素数值,返回该元素的个数。
void test2()
{set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(4);s.insert(5);cout << s.count(2) << endl;cout << s.count(6) << endl;
}

因为set的元素是唯一的,所以在set这里count可以用find来代替,但是在后面的multiset可以插入重复的元素,count就可以统计该元素的个数。
1.3 multiset
multiset和set的区别是它可以插入重复的元素。其他的接口跟set一致。头文件也跟set相同。
void test3()
{multiset<int> ms;ms.insert(1);ms.insert(1);ms.insert(2);ms.insert(3);ms.insert(4);for (auto& e : ms){cout << e << " ";}cout << endl;cout << "count(1): " << ms.count(1) << endl;
}

另外使用find查找时,如果有多个值相同,find返回的值是中序的第一个。

二、map
2.1 map的介绍

key键值对中key的类型
T键值对中value的类型
注意:
1️⃣ map中的元素总是按照键值key进行比较排序的。
2️⃣ map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
2.2 map的使用
构造和迭代器跟上面的set类似,就不过多阐述。
2.2.1 map的修改
2.2.1.1 insert

void test4()
{map<string, int> m;m.insert(pair<string, int>("a", 1));// 匿名对象m.insert(make_pair("b", 2));// 简化写法m.insert(make_pair("c", 2));m.insert(make_pair("d", 2));map<string, int>::iterator it = m.begin();while (it != m.end()){cout << (*it).first << "->" << (*it).second << endl;it++;}
}

make_pair:函数模板,不需要像pair一样显示声明类型,而是通过传参自动推导。

2.2.1.2 统计次数
1️⃣ 使用find,利用迭代器
int main()
{string arr[] = { "北京", "武汉", "广州", "上海", "北京", "北京", "广州","上海", "上海" };map<string, int> cnt;for (auto& e : arr){map<string, int>::iterator fd = cnt.find(e);if (fd == cnt.end()){cnt.insert(make_pair(e, 1));}else{fd->second++;}}for (auto& e : cnt){cout << e.first << "->" << e.second << endl;}return 0;
}

2️⃣ 使用[]
int main()
{string arr[] = { "北京", "武汉", "广州", "上海", "北京", "北京", "广州","上海", "上海" };map<string, int> cnt;for (auto& e : arr){cnt[e]++;}for (auto& e : cnt){cout << e.first << "->" << e.second << endl;}return 0;
}

[] 可以用来插入、修改、查找
[] -> (*((this->insert(make_pair(k,mapped_type()))).first)).second
// 等价于
V& operator[](const K& k)
{pair<iterator, bool> ret = insert(make_pair(k, V()));return ret.first->second;
}
这里就可以看出使用[]的时候要注意:如果没有它会直接插入。
所以我们想插入就可以:
int main()
{map<string, int> m;// 插入m["广西"];m["广东"] = 1;for (auto& e : m){cout << e.first << "->" << e.second << endl;}return 0;
}

当我们想要修改的时候不能用insert,因为只要key相同就会插入失败。
int main()
{map<string, int> m;// 插入m["广西"];m["广东"] = 1;m.insert(make_pair("广东", 2));// 插入失败for (auto& e : m){cout << e.first << "->" << e.second << endl;}return 0;
}

先要修改可以:
m["广东"] = 2;
key不在就是插入,key在就是查找。
2.3 multimap
int main()
{multimap<string, int> mm;mm.insert(make_pair("北京", 1));mm.insert(make_pair("北京", 2));mm.insert(make_pair("北京", 1));mm.insert(make_pair("上海", 1));for (auto& e : mm){cout << e.first << "->" << e.second << endl;}return 0;
}
multimap容器与map容器的底层实现以及成员函数的接口都是基本一致,而multimap的key可以重复。注意multimap没有[]。

使用multimap统计次数:
int main()
{multimap<string, int> mm;string arr[] = { "北京", "武汉", "广州", "上海", "北京", "北京", "广州","上海", "上海" };for (auto& e : arr){map<string, int>::iterator fd = mm.find(e);if (fd == mm.end()){mm.insert(make_pair(e, 1));}else{fd->second++;}}for (auto& e : mm){cout << e.first << "->" << e.second << endl;}return 0;
}

相关文章:
【C++】map和set的使用
map和set一、set1.1 set的介绍1.2 set的使用1.2.1 set的构造1.2.2 set的迭代器1.2.3 set的修改1.2.3.1 insert && find && erase1.2.3.2 count1.3 multiset二、map2.1 map的介绍2.2 map的使用2.2.1 map的修改2.2.1.1 insert2.2.1.2 统计次数2.3 multimap一、se…...
微电影广告具有哪些特点?
微电影广告是广告主投资的,以微电影为形式载体,以新媒体为主要传播载体,综合运用影视创作手法拍摄的集故事性、艺术性和商业性于一体的广告。它凭借精彩的电影语言和强大的明星效应多渠道联动传播,润物细无声地渗透和传递着商品信…...
Android RxJava框架源码解析(四)
目录一、观察者Observer创建过程二、被观察者Observable创建过程三、subscribe订阅过程四、map操作符五、线程切换原理简单示例1: private Disposable mDisposable; Observable.create(new ObservableOnSubscribe<String>() {Overridepublic void subscribe(…...
Linux信号-进程退出状态码
当进程因收到信号被终止执行退出后,父进程可以通过wait或waitpid得到它的exit code。进程被各信号终止的退出状态码总结如下:信号编号信号名称信号描述默认处理方式Exit code1SIGHUP挂起终止12SIGINT终端中断终止23SIGQUIT终端退出终止、coredump1314SIG…...
springcloud+vue实现图书管理系统
一、前言: 今天我们来分享一下一个简单的图书管理系统 我们知道图书馆系统可以有两个系统,一个是管理员管理图书的系统,管理员可以(1)查找某一本图书情况、(2)增加新的图书、(3&…...
GEE学习笔记 六十:GEE中生成GIF动画
生成GIF动画这个是GEE新增加的功能之一,这一篇文章我会简单介绍一下如何使用GEE来制作GIF动画。 相关API如下: 参数含义: params:设置GIF动画显示参数,详细的参数可以参考ee.data.getMapId() callback:回调…...
react中的useEffect
是函数组件中执行的副作用,副作用就是指每次组件更新都会执行的函数,可以用来取代生命周期。 1. 基本用法 import { useEffect } from "react"; useEffect(()>{console.log(副作用); });2. 副作用分为需要清除的和不需要清除 假如设置…...
故障安全(Crash-Safe) 复制
二进制日志记录是故障安全的:MySQL 仅记录完成的事件或事务使用 sync-binlog 提高安全性默认值是1,最安全的,操作系统在每次事务后写入文件将svnc-binloq 设置为0,当操作系统根据其内部规则写入文件的同时服务器崩溃时性能最好但事务丢失的可…...
Spring aop之针对注解
前言 接触过Spring的都知道,aop是其中重要的特性之一。笔者在开发做项目中,aop更多地是要和注解搭配:在某些方法上加上自定义注解,然后要对这些方法进行增强(很少用execution指定,哪些包下的哪些方法要增强)。那这时就…...
【JavaScript速成之路】JavaScript数据类型转换
📃个人主页:「小杨」的csdn博客 🔥系列专栏:【JavaScript速成之路】 🐳希望大家多多支持🥰一起进步呀! 文章目录前言数据类型转换1,转换为字符串型1.1,利用“”拼接转换成…...
21-绑定自定义事件
绑定自定义事件 利用自定义事件获取子组件的值 父组件给子组件绑定一个自定义事件,实际上是绑定到了子组件的实例对象vc上: <!-- 自定义myEvent事件 --> <Student v-on:myEventgetStudentName/>在父组件中编写getStudentName的实现&#…...
【Mysql】触发器
【Mysql】触发器 文章目录【Mysql】触发器1. 触发器1.1 介绍1.2 语法1.2.1 创建触发器1.2.2 查看触发器1.2.3 删除触发器1.2.4 案例1. 触发器 1.1 介绍 触发器是与表有关的数据库对象,指在insert、update、delete之前(BEFORE)或之后(AFTER),触发并执行…...
CODESYS开发教程11-库管理器
今天继续我们的小白教程,老鸟就不要在这浪费时间了😊。 前面一期我们介绍了CODESYS的文件读写函数库SysFile。大家可能发现了,在CODESYS的开发中实际上是离不开各种库的使用,其中包括系统库、第三方库以及用户自己开发的库。实际…...
【UnityAR相关】Unity Vuforia扫图片成模型具体步骤
1 资产准备 导入要生成的fbx模型(带有材质), 你会发现导入fbx的材质丢失了: 选择Standard再Extract Materials导出材质到指定文件夹下(我放在Assets->Materials了 ok啦! 材质出现了, 模型…...
2023年全国最新保安员精选真题及答案2
百分百题库提供保安员考试试题、保安职业资格考试预测题、保安员考试真题、保安职业资格证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 21.一般来说,最经济的巡逻方式是()。 A:步巡 B:…...
keil5安装了pack包但是还是不能选择device
一开始,我以为是keil5无法安装 STM32 芯片包,打开device倒是可以看到stm公司的芯片包,但是没有我想要的stm32f1。 我按照网上的一些说法,找到了这个STM32F1 的pack芯片包,但是我双击安装的时候,它的安装位…...
秒杀系统设计
1.秒杀系统的特点 瞬时高并发 2.预防措施 2.1.流量限制 对于一个相同的用户,限制请求的频次对于一个相同的IP,限制请求的频次验证码,减缓用户请求的次数活动开启之前,按钮先置灰,防止无效的请求流入系统࿰…...
全面认识数据指标体系
什么是数据指标体系? 看了下百度百科,竟然没有数据指标这个词条,看来这个词大家平时还用的不多啊。那只有间接偷懒一下,分别查下指标和数据这两个词条的含义,在组合起来看看。 数据:数据是指对客观事件进…...
热榜首推!阿里内部都在用的Java后端面试笔记,主流技术全在里面了!备战2023Java面试,拿理想offer
纵观今年的技术招聘市场, Java依旧是当仁不让的霸主 !即便遭受 Go等新兴语言不断冲击,依旧岿然不动。究其原因:Java有着极其成熟的生态,这个不用我多说;Java在 运维、可观测性、可监 控性方面都有着非常优秀…...
Android架构设计——【 APT技术实现butterknife框架 】
APT简介 APT英文全称:Android annotation process tool是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,使用Annotation进行额外的处理。 Annotation处理器在处理Annotation时可以根据源文件中的Annotation生成额外的源文…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
