c++的学习之路:25、map与set

摘要

本文中说一下map与set的使用

目录

摘要

一、关联式容器

二、键值对

三、map

1、map的介绍

2、map的使用

1、map的模板参数说明:

2、map的构造

3、map的迭代器

4、map的容量与元素访问

5、map中元素的修改

6、代码使用

​编辑

三、总结

四、set

1、set的介绍

2、set的使用

1、set的模板参数列表

2、set的构造

3、set的迭代器

4、set的容量

5、set修改操作

6、代码使用

五、multimap

1、multimap的介绍

2、multimap的使用

六、multiset

1、multiset的介绍

2、multiset的使用

七、代码

八、思维导图


一、关联式容器

关联式容器是C++标准模板库(STL)中的一种容器类型,与序列式容器(如vector、list、deque等)不同,关联式容器内部元素的存储和访问是通过关键字(key)进行有序存储的。关联式容器中的元素都是键值对(key,value)结构,并且元素会根据键值按照某种确定的规则自动排序。例如,set、map、multiset和multimap都是关联式容器。

关联式容器的主要特性包括:

1、 有序性:关联式容器中的元素按照键值进行排序。这使得关联式容器在数据检索时比序列式容器效率更高。

2、唯一性:在set和map等容器中,键值是唯一的,这保证了每个元素都能被唯一标识。

3、高效的查找:关联式容器通常使用平衡查找树(如红黑树)或哈希表来实现,这使得它们能在对数时间或常数时间内完成查找操作。

关联式容器的主要操作包括插入、删除和查找等。例如,在unordered_set容器中,可以使用insert方法插入元素,使用find方法查找元素,使用erase方法删除元素。

关联式容器在编程中有很多应用,特别是在需要快速查找、删除和插入元素的场景中。例如,在处理大量数据时,可以使用关联式容器来存储和检索数据,以提高程序的效率。

请注意,关联式容器的选择和使用应根据具体需求进行,不同的关联式容器在性能、功能和用法上可能有所差异。因此,在使用关联式容器时,应仔细考虑其特性和适用场景。

二、键值对

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

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)
{}
};

三、map

1、map的介绍

下方图片是cplusplus的介绍。翻译过来的意思就是下方六点

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通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

2、map的使用

1、map的模板参数说明:

key: 键值对中key的类型

T: 键值对中value的类型

Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)

Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
空间配置器

2、map的构造

函数声明功能介绍
map()构造一个空的map

3、map的迭代器

函数声明功能介绍
begin()和end()begin:首元素的位置,end最后一个元素的下一个位置
cbegin()和cend()与begin和end意义相同,但cbegin和cend所指向的元素不能修改
rbegin()和rend()反向迭代器,rbegin在end位置,rend在begin位置,其++和--操作与begin和end操作移动相反
crbegin()和crend()与rbegin和rend位置相同,操作相同,但crbegin和crend所指向的元素不能修改

4、map的容量与元素访问

函数声明功能简介
bool empty ( ) const检测map中的元素是否为空,是返回true,否则返回false
size_type size() const返回map中有效元素的个数
mapped_type& operator[] (constkey_type& k)返回去key对应的value

5、map中元素的修改

函数声明功能简介
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 )删除键值为x的元素
void erase ( iterator first,iterator last )删除[first, last)区间中的元素
void swap (map<Key,T,Compare,Allocator>&
mp )
交换两个map中的元素
void clear ( )将map中的元素清空
iterator find ( const key_type& x)在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end
const_iterator find ( const key_type& x ) const在map中插入key为x的元素,找到返回该元素的位置的const迭代器,否则返回cend
size_type count ( const key_type& x ) const返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中

6、代码使用

下方代码中operator[]的原理是:用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中, 如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器,如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器,operator[]函数最后将insert返回值键值对中的value返回 ,测试结果如图。

void TestMap()
{
	map<string, string> m;
	m.insert(pair<string, string>("peach", "桃子"));//构造的时候直接利用pair进行插入
	m.insert(make_pair("banan", "香蕉"));//利用make_pair函数进行插入
		m["apple"] = "苹果";//插入+修改  最常用的
		cout << m.size() << endl;
	for (auto& e : m)
		cout << e.first << "--->" << e.second << endl;
	cout << endl;
	auto ret = m.insert(make_pair("peach", "桃色"));
	if (ret.second)
		cout << "<peach, 桃色>不在map中, 已经插入" << endl;
	else
		cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
		<< ret.first->second << " 插入失败" << endl;
	m.erase("apple");
	if (1 == m.count("apple"))
		cout << "apple还在" << endl;
	else
		cout << "apple被吃了" << endl;
}

三、总结

这里是有下面6点:

1、map中的的元素是键值对

2、map中的key是唯一的,并且不能修改

3、默认按照小于的方式对key进行比较

4、map中的元素如果用迭代器去遍历,可以得到一个有序的序列

5、map的底层为平衡搜索树(红黑树),查找效率比较高$O(log_2 N)$

6、支持[]操作符,operator[]中实际进行插入查找。 

四、set

1、set的介绍

下方图片是cplusplus的介绍。翻译过来的意思就是下方五点

1、set是按照一定次序存储元素的容器

2、在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。

3、在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行
排序。

4、set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对
子集进行直接迭代。

5、set在底层是用二叉搜索树(红黑树)实现的。

 有下面8点需要注意注意:

1、与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放value,但在底层实际存放的是由<value, value>构成的键值对。

2、set中插入元素时,只需要插入value即可,不需要构造键值对。

3、set中的元素不可以重复(因此可以使用set进行去重)。

4、使用set的迭代器遍历set中的元素,可以得到有序序列

5、set中的元素默认按照小于来比较

6、set中查找某个元素,时间复杂度为:$log_2 n$

7、set中的元素不允许修改

8、set中的底层使用二叉搜索树(红黑树)来实现。

2、set的使用

1、set的模板参数列表

T: set中存放元素的类型,实际在底层存储<value, value>的键值对。

Compare:set中元素默认按照小于来比较

Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理

2、set的构造

函数声明功能介绍
set (const Compare& comp = Compare(), const Allocator&= Allocator() );构造空的set
set (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& =Allocator() );用[first,last)区间中的元素构造set
set ( const set<Key,Compare,Allocator>& x);set的拷贝构造

3、set的迭代器

函数声明功能介绍
iterator begin()返回set中起始位置元素的迭代器
iterator end()返回set中最后一个元素后面的迭代器
const_iterator cbegin() const返回set中起始位置元素的const迭代器
const_iterator cend() const返回set中最后一个元素后面的const迭代器
reverse_iterator rbegin()返回set第一个元素的反向迭代器,即end
reverse_iterator rend()返回set最后一个元素下一个位置的反向迭代器,即rbegin
const_reverse_iterator crbegin() const返回set第一个元素的反向const迭代器,即cend
const_reverse_iterator crend() const返回set最后一个元素下一个位置的反向const迭代器,即crbegin

4、set的容量

函数声明功能介绍
bool empty ( ) const检测set是否为空,空返回true,否则返回true
size_type size() const返回set中有效元素的个数

5、set修改操作

函数声明功能介绍
pair<iterator,bool> insert (const value_type& x )在set中插入元素x,实际插入的是<x, x>构成的键值对,如果插入成功,返回<该元素在set中的位置,true>,如果插入失败,说明x在set中已经存在,返回<x在set中的位置,false>
void erase ( iterator position )删除set中position位置上的元素
size_type erase ( const key_type& x )删除set中值为x的元素,返回删除的元素的个数
void erase ( iterator first,iterator last )删除set中[first, last)区间中的元素
void swap (set<Key,Compare,Allocator>&st );交换set中的元素
void clear ( )将set中的元素清空
iterator find ( const key_type& x ) const返回set中值为x的元素的位置
size_type count ( const key_type& x ) const返回set中值为x的元素的个数

6、代码使用

下面代码就是创建个数组,然后进行插入测试,因为set具有去重与排序的功能,如下图测试结果可以看出来

void TestSet()
{
	
	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	set<int> s;
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
		s.insert(arr[i]);

	cout << s.size() << endl;
	
	for (auto& e : s)
		cout << e << " ";
	cout << endl;
	
	for (auto it = s.rbegin(); it != s.rend(); ++it)
		cout << *it << " ";
	cout << endl;
	
	cout << s.count(3) << endl;
}

五、multimap

1、multimap的介绍

下方图片是cplusplus的介绍。翻译过来的意思就是下方五点

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是可以重复的。

2、multimap的使用

multimap中的接口可以参考map,功能都是类似的,这里就不具体演示了

注意:

1. multimap中的key是可以重复的。

2. multimap中的元素默认将key按照小于来比较

3. multimap中没有重载operator[]操作(同学们可思考下为什么?)。

4. 使用时与map包含的头文件相同

六、multiset

1、multiset的介绍

下方图片是cplusplus的介绍。翻译过来的意思就是下方五点:

1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。

2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。

3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则
进行排序。

4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。

5. multiset底层结构为二叉搜索树(红黑树)。
 

2、multiset的使用

multiset中的接口可以参考set,功能都是类似的,这里就不具体演示了

但是需要注意下面七点:

1. multiset中再底层中存储的是<value, value>的键值对

2. mtltiset的插入接口中只需要插入即可

3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的

4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列

5. multiset中的元素不能修改

6. 在multiset中找某个元素,时间复杂度为$O(log_2 N)$

7. multiset的作用:可以对元素进行排序

七、代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;
void TestMap()
{
	map<string, string> m;
	m.insert(pair<string, string>("peach", "桃子"));//构造的时候直接利用pair进行插入
	m.insert(make_pair("banan", "香蕉"));//利用make_pair函数进行插入
		m["apple"] = "苹果";//插入+修改  最常用的
		cout << m.size() << endl;
	for (auto& e : m)
		cout << e.first << "--->" << e.second << endl;
	cout << endl;
	auto ret = m.insert(make_pair("peach", "桃色"));
	if (ret.second)
		cout << "<peach, 桃色>不在map中, 已经插入" << endl;
	else
		cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
		<< ret.first->second << " 插入失败" << endl;
	m.erase("apple");
	if (1 == m.count("apple"))
		cout << "apple还在" << endl;
	else
		cout << "apple被吃了" << endl;
}

void TestSet()
{
	
	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	set<int> s;
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
		s.insert(arr[i]);

	cout << s.size() << endl;
	
	for (auto& e : s)
		cout << e << " ";
	cout << endl;
	
	for (auto it = s.rbegin(); it != s.rend(); ++it)
		cout << *it << " ";
	cout << endl;
	
	cout << s.count(3) << endl;
}

int main()
{
	//TestMap();
	TestSet();
	return 0;
}

八、思维导图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智慧煤矿/智慧矿区视频汇聚存储与安全风险智能分析平台建设思路

一、建设背景 目前我国非常重视煤矿安全生产&#xff0c;并投入大量资金用于煤矿安全综合远程监控系统的研发。视频监控系统作为实现煤矿智能化无人开采的关键系统与煤矿安全生产的多系统协同分析与处理的关键信息源&#xff0c;在智慧矿山管控平台的建设中发挥着重要的作用。…

【七 (1)FineBI FCP模拟试卷-股票收盘价分析】

目录 文章导航一、字段解释二、需求三、操作步骤1、添加计算字段&#xff08;每月最后一天的收盘价&#xff09;2、绘制折线图 文章导航 【一 简明数据分析进阶路径介绍&#xff08;文章导航&#xff09;】 一、字段解释 Company Name&#xff1a;公司名称 Date&#xff1a;…

8条指南教你设计奶油风客厅。福州中宅装饰,福州装修

作为一名专业的设计师&#xff0c;我将为您带来一些关于奶油风客厅设计的干货。奶油风是一种温馨、柔和的装修风格&#xff0c;以下是一些设计指南&#xff0c;帮助您打造一个舒适而美丽的奶油风客厅。 1. 色彩搭配 除了米色、浅黄色和淡粉色等基础色调&#xff0c;还可以尝试…

性能分析与调优

性能分析方法 自底向上&#xff1a;通过监控硬件及操作系统性能指标&#xff08;cpu、内存、磁盘、网络等硬件资源的性能指标&#xff09;来分析性能问题&#xff08;配置、程序问题&#xff09; 先检查&#xff0c;再下药 自顶向下&#xff1a;通过生成负载来观察被测试的系…

SEW减速机参数查询 2-2 实践

首先说说结论&#xff1a;在不和SEW官方取得沟通之前&#xff0c;你几乎无法直接通过查阅SEW官方文档得到相关减速机的所有技术参数&#xff1a;比如轴的模数和齿数&#xff0c;轴承的参数。我在周一耗费了一个上午&#xff0c;最终和SEW方面确认后才知晓相关技术参数需要凭借销…

claude不支持中国怎么办

Claude 3 是AnthropicAI 公司推出的大语言模型&#xff0c;直接对标GPT4。Claude 3 系列模型&#xff0c;包括Claude 3 Opus、Claude 3 Sonnet 和 Claude 3 Haiku。 我们完全可以依据自己的需求选用适合的模型&#xff0c;在在智能水平、处理速度和成本之间&#xff0c;找到最…

取模学习之Image2Lcd

使用软件Image2Lcd V0.4 1.&#xff1a;打开图片&#xff0c;图片格式可选如下图&#xff0c;本文使用的.jpg格式 转换后数组例子&#xff08;数组头数据占前8字节&#xff09;&#xff1a; 2.&#xff1a;扫描模式 由第1个字节低四位配置 &#xff08;1&#xff09;水平扫描 …

vue3 源码解析(7)— diff 算法源码的实现

前言 vue3 采用的 diff 算法名为快速 diff 算法&#xff0c;整个 diff 的过程分为以下5个阶段完成。 处理前置节点处理后置节点处理仅有新增节点处理仅有删除节点处理其他情况&#xff08;新增 / 卸载 / 移动&#xff09; 这里我们先定义新旧两个节点列表&#xff0c;接下来…

再生龙(Clonezilla)网络克隆linux系统实现迁移——筑梦之路

官方网站&#xff1a;Clonezilla - 簡介 环境说明 源端&#xff1a;CentOS 7 操作系统的虚拟机&#xff0c;硬盘大小为 40GiB&#xff0c;分为 1GiB 的 /boot&#xff08;启动&#xff09;分区、4GiB 的 swap&#xff08;交换&#xff09;分区和 35GiB 的 /&#xff08;根&…

K8S一 k8s基础知识及实战

一 K8S 概览 1.1 K8S 是什么&#xff1f; K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ K8S 是Kubernetes的全称&#xff0c;源于希腊语&#xff0c;意为“舵手”或“飞行员”&#xff0c;官方称其是&#xff1a;用于自动部署、扩展和管理“容器化&#xff08…

LeetCode in Python 509. Fibonacci Number (斐波那契数)

斐波那契数实现方式有多种方法&#xff0c;最容易理解的为递归法&#xff0c;也可使用动态规划降低时间复杂度&#xff0c;本文给出递归法和动态规划两种方法的代码实现。 示例&#xff1a; 图1 斐波那契数输入输出示例 方法一&#xff1a;递归法 代码&#xff1a; class …

如何在本地创建一个贪吃蛇小游戏node.js服务并实现无公网IP远程游玩

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽…

CoFSM基于共现尺度空间的多模态遥感图像匹配方法--论文阅读记录

目录 论文 Multi-Modal Remote Sensing Image Matching Considering Co-Occurrence Filter 参考论文&#xff1a;SIFT系列论文&#xff0c; SIFT Distinctive Image Features from Scale-Invariant Keypoints&#xff0c;作者&#xff1a;David G. Lowe 快速样本共识算法…

Leetcode 53. 最大子数组和

心路历程&#xff1a; 子数组的和是可以通过前面的和加上当前值递推获得&#xff0c;所以可以用动态规划解决这道题 注意的点&#xff1a; 1、这道题再获取最大值时res不能用0而需要用负无穷初始化 解法&#xff1a;动态规划 class Solution:def maxSubArray(self, nums: …

(十三)C++自制植物大战僵尸游戏多用户存档实现(二)

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs UserData.h 在头文件中定义了枚举类型openUserDataReturnType&#xff0c;用于表示打开用户数据文件的返回状态。FileExistError表示文件存在但是打开错误&#xff0c;FileExistCorrect表示文件在且正确&#xff0…

Python | Leetcode Python题解之第29题两数相除

题目&#xff1a; 题解&#xff1a; class Solution:def divide(self, dividend: int, divisor: int) -> int:INT_MIN, INT_MAX -2**31, 2**31 - 1# 考虑被除数为最小值的情况if dividend INT_MIN:if divisor 1:return INT_MINif divisor -1:return INT_MAX# 考虑除数为…

Pandas数据分析学习笔记

前言 开刷Pandas数据分析&#xff0c;看起来很好理解&#xff0c;不过没做笔记没敲代码心里总是不安稳&#xff0c;所以复现下课程代码并演示其中遇到的问题&#xff0c;顺便水一水笔记好了 参考资料&#xff1a; 课程视频链接&#xff1a;Pandas数据分析从入门到实战 数据…

Halo自定义页面

在使用Halo后台维护项目&#xff0c;有的页面是固定的&#xff0c;但内容需要一些自定义样式&#xff0c;内容动态编辑生成&#xff0c;这个时候就需要自定义页面; Halo版本 版本&#xff1a;2.121.首先在theme.yaml中添加自定义页面并指定文件名 spec:customTemplates:page:…

面试题集中营—GC日志简析及频繁GC的调优

如何查看GC日志 有两种方式查看GC日志&#xff0c;一种是动态命令行查看 jstat -gc <pid> 300 5 第二种就是在JVM参数中增加打印的参数&#xff0c;如下&#xff1a; -XX:PrintGCDetails -XX:PrintGCTimeStamps 表示打印每次GC的日志以及GC发生的时间 -Xloggc:gc.log …

如何解决PPT中获取加载项是灰色的,无法链接到Power BI的问题?

问题描述&#xff1a; 最近有朋友留言询问:“在尝试之前我发布的如何在PPT中展示Power BI报告的操作步骤的时候&#xff0c;想要在PPT中展示Power BI报告&#xff1f;只需这样做&#xff01; (qq.com) 碰到在PowerPoint中【获取加载项选项】是灰色&#xff0c;无法链加载Powe…