C++:set和map的使用
set和map的使用
- 1.关联式容器
- 2.key模型和key_value模型
- 3.set
- 3.1一些注意点
- 3.2set的使用
- 3.3习题
- 4.multiset
- 5.map
- 5.1一些注意点
- 5.2map的使用
- 5.3习题
- 6.multimap
1.关联式容器
序列式容器:比如我们之前讲的vector、string、list等均为序列式容器,特点是按元素顺序来保存和访问。
关联式容器:比如本次讲的map和set,和序列式容器不同,其依靠键值来保存和访问,数据检索效率闭序列式容器高。
PS:本文只讲使用,set和map底层是一颗平衡二叉搜索树。
2.key模型和key_value模型
(1)key模型:主要解决在不在的问题?比如现在录入人脸信息,用户登录的判断就可以采用key模型,set其实就是一个key模型。
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;int main() {set<string> s;vector<string> v = {"张三", "李四", "王五", "赵六"};for (auto e : v) s.insert(e); //还没讲接口,这里的作用是录入信息string input;while (cin >> input){if (s.count(input)) //这里的作用是在set中查找input是否存在{cout << "存在,查找成功" << endl;}else{cout << "不存在" << endl;}}return 0;
}
(2)key_value模型:和key模型最大的不同就是存储,key模型只存一个键值,而key_value模型存储的是一个键值对。除了可以解决在不在的问题,还可以通过键值找到对应信息,map其实就是一个key_value模型。
键值对:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量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){}
};int main() {//还没讲接口,知道大概意思就行map<string, string> mapTranslation; //就以英汉翻译词典为例子//录入词典的信息mapTranslation.insert(make_pair("left", "左边"));mapTranslation.insert(make_pair("right", "右边"));mapTranslation.insert(make_pair("sort", "排序"));mapTranslation.insert(make_pair("father", "父亲"));string input;while (cin >> input){if (mapTranslation.count(input)) //这里也是查找在不在{cout << "中文为: " << mapTranslation[input] << endl; //这里拿到value}else{cout << "词典无记录" << endl;}}return 0;
}
3.set
3.1一些注意点
- set不允许键值冗余,比如插入3后不能再插入3。拒绝键值冗余,本就是二叉搜索树的定义。故set中不会有重复的元素,可以利用这一点对数据进行去重。
- set利用迭代器遍历元素,可以得到一个有序序列,可利用这一点对数据进行排序。原理是中序遍历二叉搜索树可以得到有序序列。
- set元素默认按小于比较,即默认升序。
- set不允许修改元素,如果支持修改会无法维护搜索二叉树的结构。
- set中查找某个元素,时间复杂度为:logN
3.2set的使用
(1)模板参数
(2)构造
函数声明 | 功能 |
---|---|
set (const Compare& comp = Compare(), const Allocator& = Allocator()) | 空构造 |
set (InputIterator first, InputIterator last, 后面和空构造一样) | 迭代器区间构造 |
set (const set& x) | 拷贝构造 |
(3)迭代器
函数声明 | 功能 |
---|---|
iterator begin() | 返回set中起始位置元素的迭代器 |
iterator end() | 返回set中最后一个元素后面的迭代器 |
reverse_iterator rbegin() | 反向迭代器,返回end() |
reverse_iterator rend() | 反向迭代器,返回begin()的前一个位置 |
(4)容量
函数声明 | 功能 |
---|---|
bool empty ( ) const | 检测set是否为空,空返回true,否则返回false |
size_type size() const | 返回set中有效元素的个数 |
(5)增加、删除、查找
函数声明 | 功能 |
---|---|
pair<iterator,bool> insert ( const value_type& x ) | 在set中插入元素x,实际插入的是<x, x>构成的键值对,如果插入成功,返回<该元素在set中的位置,true>;如果插入失败,说明x在set中已经存在,返回<x在set中的位置,false> |
void erase ( iterator position) | 删除对应position位置的元素 |
size_type erase ( const key_type& x ) | 删除set中值为x的元素,返回删除的元素的个数 |
void erase ( iterator first, iterator last ) | 删除set中[first, last)区间中的元素 |
iterator find ( const key_type& x ) const | 返回set中值为x的元素的迭代器,不存在返回end() |
size_type count ( const key_type& x ) const | 返回set中值为x的元素的个数 |
void swap (set& sp ) | 交换两个set中的元素 |
void clear ( ) | 将set中的元素清空 |
几个注意点:
- insert的返回值希望大家记一下,方便大家理解map的核心接口。
- 判断键值在不在set中有两种方法:
第一种是find(key),依据返回值判断,是end()代表不在,否则存在。
第二种是count(key),如果存在返回非0,不存在返回0,也可以进行判断。
选择习惯的方式即可。
3.3习题
链接:两个数组交集
题目要求:
代码加解析:
//主要思想是利用set进行去重
//(1)先用set1存储nums1的值,比如[1,2,2,1]->[1,2](set去重)
//(2)定义一个set2,如果nums2的值在set1中可以找到,就插入set2中
//注意:因为nums2中可能存在多个相同值,故用set可以进行去重
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> set_exist;set<int> result;for(auto e : nums1){set_exist.insert(e);}for(auto e : nums2){if(set_exist.find(e) != set_exist.end()) //如果存在{result.insert(e);}}return vector<int>(result.begin(), result.end());}
};//这个题也可以先去重加排序
//交集:(1)不相等小的加加;(2)相等是交集,同时加加
//差集:(1)不相等小的是差集,小的加加;(2)相等都不是差集,同时加加 (3)一方走完,剩下的都是差集
4.multiset
multiset和set使用几乎一致,唯一的不同就是允许键值冗余。
- 迭代器遍历依然可以得到有序序列
- count()接口对multiset非常重要
- multiset的find()查找返回的是中序遍历的第一个元素。
- multiset可以对存在重复元素的序列排序。
5.map
5.1一些注意点
- 在内部,map中的元素总是按照键值key进行比较排序的,和value无关。
- map不允许键值冗余,map中的键值对是唯一的。
- 利用迭代器遍历可以得到有序序列,不过是按key来排序。
- map不允许修改key,但可以修改value。支持修改键值会无法维护二叉搜索树结构。
- map中查找某个元素,时间复杂度为:logN
5.2map的使用
(1)模板参数
(2)构造
函数声明 | 功能 |
---|---|
map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()) | 空构造 |
map (InputIterator first, InputIterator last, 后面和空构造一样) | 迭代器区间构造 |
map (const map& x) | 拷贝构造 |
(3)迭代器
函数声明 | 功能 |
---|---|
iterator begin() | 返回set中起始位置元素的迭代器 |
iterator end() | 返回set中最后一个元素后面的迭代器 |
reverse_iterator rbegin() | 反向迭代器,返回end() |
reverse_iterator rend() | 反向迭代器,返回begin()的前一个位置 |
(4)容量
函数声明 | 功能 |
---|---|
bool empty ( ) const | 检测set是否为空,空返回true,否则返回false |
size_type size() const | 返回set中有效元素的个数 |
(5)增加、删除、修改、查找
函数声明 | 功能 |
---|---|
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 ) | 删除map中键值为x的元素,返回删除的元素的个数 |
void erase ( iterator first, iterator last ) | 删除map中[first, last)区间中的元素 |
iterator find ( const key_type& x ) const | 返回map中键值为x的元素的迭代器,不存在返回end() |
size_type count ( const key_type& x ) const | 返回map中键值为x的元素的个数 |
mapped_type& operator[] (const key_type& k) (非常重要) | 返回key对应的value |
void swap ( map& mp ) | 交换两个map中的元素 |
void clear ( ) | 将map中的元素清空 |
几个注意点:
- 这里的接口中最重要的就是operator[],因为[]不仅可以访问value,还可以进行插入。
operator[]的原理是: 用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中如果key已经存在,插入失败,如果不存在就进行插入。insert返回的键值对第一个元素就是元素对应的迭代器,operator[]函数通过迭代器最后返回键值对中的value的引用。 - 对map的迭代器解引用得到是键值对结构体,设迭代器为x,拿value的方式有两种。(*x).second或x->second。
- map判断键值对在不在的方式和前面set一致。
5.3习题
链接:前k个高频单词
题目要求:
代码加解析:
//这里的核心思路:
//(1)用map统计每个字符串出现次数
//(2)对键值对进行排序,出现次数相同的要按字典序来排
// 因为键值对自带的比较规则是只按key排序的,所以我们需要自定义排序(比较方法)
//其实只是访问的话unordered_map更加快速,但unordered_map迭代器遍历无法保证有序
class compare
{
public:bool operator()(pair<string,int> p1, pair<string,int> p2) const{if(p1.second == p2.second){//出现次数相同,按字典序排return p1.first < p2.first;}else{//要排降序,按大于排return p1.second > p2.second;}}
};
class Solution {
public:vector<string> topKFrequent(vector<string>& words, int k) {map<string, int> count_map; //用map统计for(int i = 0; i < words.size(); i++){count_map[words[i]] ++;}//排序(降序)vector<pair<string,int>> result(count_map.begin(), count_map.end());;sort(result.begin(),result.end(),compare());vector<string> ret;for(int i = 0; i < k; i++)ret.push_back(result[i].first);return ret;}
};
//也可以利用set进行排序
// set<pair<string, int>, compare> sort_set(count_map.begin(), count_map.end());
// vector<string> ret;
// auto it = sort_set.begin();
// while(k--)
// {
// ret.push_back(it->first);
// it++;
// }
// return ret;
6.multimap
multimap和map使用几乎一致,最大的不同就是允许键值冗余。
- multimap没有支持operator[]。
原因是存在多个同键值的键值对,不知道取谁的value。 - 迭代器遍历依然可以得到有序序列。
- count()接口对multimap非常重要。
- multimap的find()查找返回的是中序遍历的第一个元素。
- multimap可以对存在重复元素的序列排序。
相关文章:

C++:set和map的使用
set和map的使用 1.关联式容器2.key模型和key_value模型3.set3.1一些注意点3.2set的使用3.3习题 4.multiset5.map5.1一些注意点5.2map的使用5.3习题 6.multimap 1.关联式容器 序列式容器:比如我们之前讲的vector、string、list等均为序列式容器,特点是按…...

同城售后系统退款业务重构心得 | 京东云技术团队
一、重构背景 1.1、退款 到家、小时购、天选退款有2套结构,代码逻辑混乱; 其中小时购、天选部分售后单是和平生pop交互退款,部分是和售后中台交互退款;并且兼容3套逻辑; 痛点:代码繁重,缺乏…...

【计算机网络笔记】TCP连接管理(图解三次握手和四次挥手)
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...

C++ 初阶 类和对象(中)
前言:C初阶系列,每一期博主都会使用简单朴素的语言将对应的知识分享给大家,争取让所有人都可以听懂,C初阶系列会持续更新,上学期间将不定时更新,但总会更的 目录 一、构造函数 1.1为什么要有构造函数&…...

【漏洞复现】Metinfo5.0.4任意文件包含漏洞复现
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1、蚁剑直接连接图片马2、读取敏感目录3、读取php源码4、执行PHP命令5、包含木马写Shell (图片马制作新方法) 以 metinfo_5.0.4为例 该环境的文件上传…...

【计算机网络实验/wireshark】tcp建立和释放
wireshark开始捕获后,浏览器打开xg.swjtu.edu.cn,网页传输完成后,关闭浏览器,然后停止报文捕获。 若捕获不到dns报文,先运行ipconfig/flushdns命令清空dns缓存 DNS报文 设置了筛选条件:dns 查询报文目的…...

STM32:I²C通信原理概要
一、IIC通信原理 IIC通信和串口通信有一定的相似之处,都有一根共地线和两根数据线。但是传递外部信息,串口有两根数据线可以进行双向通信,也就是全双工通信。而在IIC通信下,其中一条数据线是用于提供同步时钟脉冲的时钟线(SCL)&am…...
【开题报告】基于 Spring Boot 的在线预约导游系统的设计与实现
1.引言 在旅游行业中,导游起到了重要的作用,他们为游客提供了专业的旅游服务和相关信息。然而,传统的导游预约方式可能存在一些问题,如信息不透明、预约流程繁琐等。因此,我们计划开发一个基于 Spring Boot 的在线预约…...

如何使用ps制作ico图标文件
如何使用ps制作ico图标文件 Chapter1 如何使用ps制作ico图标文件Chapter2 ICOFormat.8bi(Photoshop Ico、Cur插件)的下载使用1. ICOFormat.8bi的作用2. ICOFormat.8bi使用 Chapter3 ps手机计算机图标教程,手绘设计精美手机APP软件图标的PS教程步骤 01 制…...
【Linux】logrotate实现“日志文件定时分割“
问题背景 项目部署的过程中,经常会需要查看程序的执行日志。我之前的做法都是用nohup ... > xxx.log 2>&1 &将日志保存到xxx.log文件中的。但是问题是,程序有时会运行很长时间,一直保存在一个文件里,文件会越来越大…...

Android可绘制资源概览(背景、图形等)
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、drawable 分类3.1 Bitmap fileXML …...
力扣2095.删除链表的中间节点(java快慢指针)
Problem: 2095. 删除链表的中间节点 文章目录 思路解题方法复杂度Code 思路 利用快慢指针,快指针每次走两步,慢指针每次走一步(循环退出条件是fast指针不为空同时fast.next不为空),但是我们容易发现这样到最后slow指针…...
【Vue-Element-Admin】table添加自定义索引
通过给 typeindex 的列传入 index 属性,可以自定义索引。该属性传入数字时,将作为索引的起始值。也可以传入一个方法,它提供当前行的行号(从 0 开始)作为参数,返回值将作为索引展示。 <el-table:data&q…...

0008Java安卓程序设计-ssm基于Android平台的健康管理系统
文章目录 **摘要**目录系统实现开发环境 编程技术交流、源码分享、模板分享、网课教程 🐧裙:776871563 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,…...
Mac 禁用一些高占用cup的进程
什么是CrashReporter? CrashReporter在应用程序崩溃的任何时候都会运行,它旨在保存应用程序状态,以帮助开发人员找出应用程序崩溃原因。基本上,一个进程是启动、崩溃(并调用CrashReporter),然后…...

layui form表单 调整 label 宽度
这个可以调整所有label .layui-form-label {width: 120px !important; } .layui-input-block {margin-left: 150px !important; }情况是这样的,表单里有多个输入框,只有个别label 是长的,我就想调整一下个别长的,其它不变 <di…...

轻量封装WebGPU渲染系统示例<12>- 基础3D对象实体(源码)
当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/main/src/voxgpu/sample/PrimitiveEntityTest.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 细节请见:引擎系统设计思路 - 用户态与系统态隔离-CSDN博客 2. 高频调用与低频调用隔…...

[ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
业务需求:需要做到table表格中某些行数据不能被选中,比如在审核一些记录数据时,已经被审核的数据就不能再次提交审核,特别是批量多选的情况,列表中既有已经审核的,也有未审核的,只要求选中未审核…...
【PY】倒计时日历
大家有时候会不会觉得时间记不住呢?PY倒计时日历可以满足你。 main.py: from tkinter import Tk,Canvas from datetime import date,datetime def get_events():list_events[]with open(events.txt)as file:for line in file:lineline.rstrip(\n)curre…...

windows mysql安装
1、首先去官网下载mysql安装包,官网地址:MySQL :: Download MySQL Community Server 2:把安装包放到你安装mysql的地方,然后进行解压缩,注意,解压后的mysql没有配置文件,我们需要创建配置文件 配…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...