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

map和set的使用指南

1.关联式容器和序列式容器

在我们之前的学习当中,vector,list,deque,forward_list为序列式容器,(stack,queue为容器适配器,这里顺带着大家复习一下,如果忘记了可以看前面的篇章),而我们今天学习的map和set为关联式容器。

其两者的根本区别序列式容器存储的是数值本身,而我们的关联式容器存储的是**<key,value>类型的键值对**

键值对的介绍:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。

其实我们今天要讲的map和set其底层是一种以树形结构的关联式容器——红黑树,这个在之后的文章会为大家一一讲解。

2.set的使用

2.1 set的模板参数列表

在这里插入图片描述

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

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

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

2.2set的常见使用案例插入
int main()
{
	set<int> a;
	multiset<int> b;
	a.insert(2);
	a.insert(2);
	a.insert(1);
	a.insert(3);

	b.insert(2);
    b.insert(2);
	b.insert(1);
    b.insert(3);
	set<int>::iterator pos1 = a.begin();
	while (pos1 != a.end())
	{
		cout << *pos1 << "";
		pos1++;
	}
	cout << endl;

	multiset<int>::iterator pos2 = b.begin();
	while (pos2 != b.end())
	{
		cout << *pos2 << "";
		pos2++;
	}
}

在这里插入图片描述
这里设计到了multiset,其作用就是不去重。

上段代码以及编译结果可以看出,set的插入会自动去重,而且会排序(底层用的快排,当然在char类的排序中运用的适合strcpy一样的原理,在底层树形结构中用的也是中序遍历),而我们的multiset除了不去重之外,其余接口都和set的使用方式一样。

2.3此类问题一些迭代器的用法以及感悟

首先map也好set也罢其底层用的容器是列表,具之前文章所刨析,列表迭代器需要重新封装,所以最后其用法与string,vector等无异(都认为其类型为一个指针变量),只是不能遍历。

当然在此有个需要注意的地方,list迭代器的将“—>"重载时,其返回的是当前变量的地址。

2.4 set的删除
int main()
{
	set<int> a;
	multiset<int> b;
	a.insert(2);
	a.insert(2);
	a.insert(1);
	a.insert(3);
	set<int>::iterator pos = a.begin();
	set<int>::iterator pos2 = a.find(3);
	int re = a.erase(2);
	a.erase(pos2);
	cout << re << endl; 
	while (pos != a.end())
	{
		cout << *pos;
		pos++;
	}	
     cout << endl;
}

在这里插入图片描述

首先这里用了删数字和地址的方式删除了2,3,其次其erase函数返回规则是删除几个数返回几,如果没删除返回0。

tips:在multiset当中使用find的话如果恰巧找的那个数是重复的,那么将返回中序第一个val值所在结点的迭代器。

​ *pos无非被修改,因为它是一个数的结构,贸然修改其结构不保。

3.map的使用

3.1map的模板参数说明

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E9Hww6qX-1679380899185)(C:\Users\山野村居\Desktop\4.png)]

key: 键值对中key的类型

T: 键值对中value的类型

Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比

较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户

自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)

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

tips:当key不存在时,operator[]用默认value与key构造键值对然后插入,返回该默认value,at()函数直接抛异常

3.2map插入
int main()
{
	map<string, string> a;
	pair<string, string> b("telephone","电话");
	a.insert(b); 
	a.insert(pair<string, string>("cake", "蛋糕"));//需要写明白类型
	a.insert(make_pair("love", "爱"));//自动推导类型,函数返回的是pair
	map<string, string>::iterator it = a.begin();
	while (it != a.end())
	{
		cout << (*it).first << endl;// "."的优先级比*高所以加(),first指向的是key,second指向的是value,当然了我们正常是直接使用->符号,但是这样编译器会省略一个->,因为容器list对->的重载返回的是地址
		it++;
	}
}

在这里插入图片描述

这里的插入比起set来说细节更多,请一定要多多注意理解。

3.3对于for快捷遍历的一些思考

在这里插入图片描述
在这里插入图片描述

3.4map对[ ]运算符的重载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UpbHvXVE-1679380899187)(C:\Users\山野村居\AppData\Roaming\Typora\typora-user-images\image-20230321141803007.png)]

从这张图片可以看出其返回的是mapped_type类型的引用,而我们的里面实际上是pair这个对象里面的second

相当于key,value这个模型中给个key能访问到其value。(tips:multimap 里面没有重载multimap此外在multimap中还有一个常用的cout计数函数

使用案例演示:

int main
{
    map<string,string> a;
    a.insert(make_pair("a","小明"));
    a.insert(make_pair("b","小红"));
    a.insert(make_pair("c","小张"));
    a["a"] = "小李"; //修改
    a["d"]; //当没有这个key时自动插入
    cout<<a["c"]; //打印结果为小张
    return 0;
}

http://www.kler.cn/a/1977.html

相关文章:

  • Unity 6 Preview(预览版)新增功能
  • 混合开发环境---使用编程AI辅助开发Qt
  • Docker Compose 安装 Harbor
  • 2024年图像处理、多媒体技术与机器学习
  • OpenHarmony-6.IPC/RPC组件
  • 深度学习试题及答案解析(二)
  • 电脑技巧:常见的浏览器内核介绍
  • Cookie和Session详解
  • 基于YOLOv5的疲劳驾驶检测系统(Python+清新界面+数据集)
  • PCL 使用ICP点云拼接
  • 如何监控和诊断JVM堆内和堆外内存使用?
  • 简单三步解决动态规划难题,记好这三步,动态规划就不难
  • 图神经网络的数学原理总结
  • JavaSE思维导图——总结篇
  • 前端已死?后端已亡?弯弯绕绕,几分真几分假
  • HCIE-Cloud Computing LAB备考第二步:逐题攻破--第五题:规划--根据网络平面规划表,完成ensp中接入交换机SW1/2的配置
  • GIS应用技巧之图斑四至坐标计算
  • 【Linux】环境变量(基本概念 常见环境变量 测试PATH 环境变量相关命令)
  • Java 注解(详细学习笔记)
  • RK3588平台开发系列讲解(视频篇)RTP H264 码流打包详解
  • 硬件速攻-AT24CXX存储器
  • 常见背包问题
  • 三月份跳槽了,历经字节测开岗4轮面试,不出意外,被刷了...
  • centos7安装mysql5.7.4(rpm安装版)与 MySQL5.7.4glibc版Linux安装
  • linux console快捷键
  • 如何设计一个锂电池充电电路(TP4056)