Cpp9 — map和set

 map和set

STL分为序列式容器(vector、list、deque)和关联式容器(map、set)

序列式容器:数据与数据之间没有很强的联系。(各个数据之间没什么关联)。底层为线性序列的数据结构,里面存储的是元素本身。栈和队列是适配器。

关联式容器:数据和数据之间有很强的关联关系(在数据检索时比序列式容器效率更高。底层是红黑树,再底层是一棵搜索树。)

set

set的本质是Key模型(Key模型就是确认在不在的模型)。典型的set底层是二叉搜索树

Compare是一个仿函数,用来比较。默认给的是less,相当于operator<,我们可以传别的,来控制这里的比较规则、比较方式。

 key_comp/value_comp获取key/value的比较器。  提供它两是为了保持set与map的一个兼容

set支持增删查,不支持修改,因为Key模型的底层是二叉搜索树,其一旦被修改,整个树就有可能错误了,所以是不允许修改的。

set的拷贝构造赋值都是深拷贝,而且是一棵树,消耗比较大。

lower_bound、upper_bound

删除30-60

itlow = lower_bound(30);//返回大于等于30这个的值的位置//如果给35,则是40到60

itup = upper_bound(60);//返回大于60这个的值的位置,这里返回的是70//如果给55,返回的是60的位置,但是因为是左闭右开,所以60并没有被删掉

//10 20 30 40 50 60 70 80 90

set.erase(itlow, itup);//删除30到70所括住的区间[30, 70)

equal_range

x <= val < y(左闭右开)

map 

 map底层存储的结构是pair,pair是一个模板的键值对。map的底层是一棵树

pair的原型大致为

 这是SGI-STL原码中对于键值对的定义

 这里能不能用auto推导?不能,它推不出来

因为其插入时,只看key,val相不相同无所谓,但是map不支持冗余,所以只要key有了,就不支持再插入了。

 其实也不用typedef pair

我们可以用make_pair。前面的都是调用构造。而make_pair是一个函数模板,它的实现方式大致如下,它的优势就是自动推导,不需要我们显式地写模板参数了。make_pair是构造一个匿名pair然后返回

 一般被定义成inline

 有时候有些头文件我们每包含,但是我们仍能使用的原因:

它们被其他头文件包含了。

map的遍历

void test_map1()
{
	map<string, string> dict;
	pair <string, string> kv1("hello","你好");
	dict.insert(kv1);
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("push", "插入"));
	dict.insert(make_pair("pop","删除"));

	//dict.insert(make_pair("hello", "hi"));//优势:自动推导类型,不用显式地写模板参数

	//map的遍历
	map<string, string>::iterator it = dict.begin();
	//auto it = dict.begin();
	while (it != dict.end())
	{
	    cout << it->first << it->second << endl;
		//cout << (*it).first <<(*it).second << endl;//pair不支持流插入,它没有重载流插入。
		//我们用kv键值对
		++it;
	}
	cout << endl;
	for (const auto& kv : dict)//范围for是依次取数据赋值给kv,其实就是迭代器*it给kv,但是这样拷贝代价太大了,所以尽量把引用加上减少拷贝。
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;

}

map和set的迭代器都是双向迭代器,也就是可以正向和反向遍历。

第三十节00:11:00-00:25:00 将双箭头做特殊处理 只看了一遍,没笔记,代码只写了一点

map中的[]

它去容器里找k对应的元素,然后返回对应的value。如果这个key没有被匹配到,它会插入一个新的元素,这个元素就用这个key,然后返回它的映射类型,如果它没有对应的映射类型,value用它的默认构造(default constructor)

即:

1.map中有这个key,返回value的引用(可用于查找,修改value)

2.map中没有这个key,会插入一个新元素,该元素为pair(key, V()); ,返回value(这里的value就是pair里自动创建的value)的引用(可用于插入,修改)    V()是value类型的匿名对象。这个value是一个缺省值,该value如果是int类型,则其缺省值为0,若为string,则其为"",若为指针,则其为nullptr

[]的底层是这样实现的

 map中的insert

上面的value_type实际上就是pair<K, V> val;

返回的不是true和false,而是pair

 insert一个值,如果已经有这个值了,就不插入,bool就是false。如果没有,那就插入,bool是true

再讲解:

返回一个pair,pair的first被设置为迭代器,这个迭代器指向新插入的元素或者是跟这个key相等的元素,second是bool,如果插入成功,返回true。如果插入失败(即有key与它相等),则返回false。

插入时只看key。

1.key已经在map中,返回pair<key_iterator, false>//返回新插入元素的迭代器或与这个值相等的元素的迭代器;如果与key相等的元素已经存在,返回false(即已存在且相等的话,返回false)

2.key不在map中,返回pair(new_key_iterator, true);

第三十节1:06:30-1:15:00模拟实现[]

insert返回pair就是为[]准备的。

multimap为什么没有[]呢?

因为它允许键值冗余了,例如我们要返回苹果,我们应该返回哪次苹果来时的value呢?multi也不能用之前的代码帮我们统计次数了,因为它可以多次插入一样的值。

multimap也是看key,但是不管key有没有出现过,它都是插入,value相不相同无所谓

两个题:第三十节1:38:40-2:58:00

unordered_map、unordered_set

map/set与unordered系列的区别

1.map和set遍历是有序的,该类为无序

2.unordered系列只有单向迭代器,map和set是双向迭代器

数据越多,unordered系列效率更高,但是它的插入稍微差一点,因为它插入时要扩容,扩容的代价有点大

unordered系列的优点:

在处理大量数据时,其增删查改效率更优,尤其是查找。

当我们遇到这种情况时(一个不能被运算的类型需要运算)。

unordered_map里有一个参数帮助我们解决这种情况。hash<Key>

hash<Key>是一个仿函数,

所以要在这里添加一个Hash的仿函数

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

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

相关文章

【云原生K8s】二进制部署单master K8s+etcd集群

一、实验设计 mater节点master01192.168.190.10kube-apiserver kube-controller-manager kube-scheduler etcd node节点node01192.168.190.20kubelet kube-proxy docker (容…

elementUI全屏loading的使用(白屏的解决方案)

官网中有使用方法&#xff0c;但是我实际上手之后会出现白屏&#xff0c;解决办法如下&#xff1a; <el-button type"text" size"small" click"delRow(scope)"> 删除</el-button>loading: false, // loading 动画loadingInstance…

ubuntu下,在vscode中使用platformio出现 Can not find working Python 3.6+ Interpreter的问题

有一段时间没有使用platformio了&#xff0c;今天突然使用的时候&#xff0c;发现用不了&#xff0c;报错&#xff1a; Ubuntu PlatformIO: Can not find working Python 3.6 Interpreter. Please install the latest Python 3 and restart VSCode。 上网一查&#xff0c;发现…

【NLP概念源和流】 06-编码器-解码器模型(6/20 部分)

一、说明 在机器翻译等任务中,我们必须从一系列输入词映射到一系列输出词。读者必须注意,这与“序列标记”不同,在“序列标记”中,该任务是将序列中的每个单词映射到预定义的类,如词性或命名实体任务。 作者生成 在上面的

基于回溯算法实现八皇后问题

八皇后问题是一个经典的计算机科学问题&#xff0c;它的目标是将8个皇后放置在一个大小为88的棋盘上&#xff0c;使得每个皇后都不会攻击到其他的皇后。皇后可以攻击同一行、同一列和同一对角线上的棋子。 一、八皇后问题介绍 八皇后问题最早由国际西洋棋大师马克斯贝瑟尔在18…

计算机视觉与图形学-神经渲染专题-第一个基于NeRF的自动驾驶仿真平台

如今&#xff0c;自动驾驶汽车可以在普通情况下平稳行驶&#xff0c;人们普遍认识到&#xff0c;真实的传感器模拟将在通过模拟解决剩余的极端情况方面发挥关键作用。为此&#xff0c;我们提出了一种基于神经辐射场&#xff08;NeRF&#xff09;的自动驾驶模拟器。与现有作品相…

7_分类算法—逻辑回归

文章目录 逻辑回归&#xff1a;1 Logistic回归&#xff08;二分类问题&#xff09;1.1 sigmoid函数1.2 Logistic回归及似然函数&#xff08;求解&#xff09;1.3 θ参数求解1.4 Logistic回归损失函数1.5 LogisticRegression总结 2 Softmax回归&#xff08;多分类问题&#xff0…

Nginx安装和Nginx配置虚拟主机

Nginx安装 源码包获取地址&#xff1a;http://nginx.org/download/ RPM包获取地址&#xff1a;http://nginx.org/packages/centos/7Server/x86_64/RPMS/ RPM安装 这里选择的RPM包是 nginx-1.22.0-1.el7.ngx.x86_64.rpm [rootlocalhost ~]# yum install nginx-1.22.0-1.el7.…

【项目 进程12】2.25 sigprocmask函数使用 2.26sigaction信号捕捉函数 2.27SIGCHILD信号

文章目录 2.25 sigprocmask函数使用2.26 sigaction信号捕捉函数内核实现信号捕捉的过程信号捕捉特性 2.27SIGCHILD信号 2.25 sigprocmask函数使用 阻塞信号集有时称作信号掩码。 联想&#xff1a;fcntl函数可以修改fd属性。 ./sigprocmask & //将程序设置为后台运行&…

深度学习论文: Towards Total Recall in Industrial Anomaly Detection及其PyTorch实现

深度学习论文: Towards Total Recall in Industrial Anomaly Detection及其PyTorch实现 Towards Total Recall in Industrial Anomaly Detection PDF: https://arxiv.org/pdf/2106.08265.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://…

2.4G芯片XL2408开发板,SOP16封装,芯片集成1T 8051内核单片机

XL2408开发板可用于2.4G芯片XL2408开发板的开发调试。XL2408烧录仿真需要使用WS_LINK。XL2408开发板烧录仿真需要接4根线&#xff1a;PA13:DIO&#xff0c;PA14:CLK&#xff0c;VCC&#xff0c;GND。 XL2408芯片集成射频收发机、频率收生器、晶体振荡器、调制解调器等功能模块,…

CentOS 7.6使用yum安装stress,源码安装stree-ng 0.15.06,源码安装sysstat 12.7.2

cat /etc/redhat-release看到操作系统的版本是CentOS Linux release 7.6.1810 (Core)&#xff0c;uname -r可以看到内核版本是3.10.0-957.21.3.el7.x86_64 yum install stress sysstat -y安装stress和sysstat。 使用pidstat -u 5 1没有%wait项&#xff1a; 原因是CentOS 7仓…

1分钟解决github push/pull报错443

1.打开https://www.ipaddress.com/ 2.复制如图IP地址 3.文件夹打开C:\Windows\System32\drivers\etc&#xff0c;复制hosts文件&#xff0c;粘贴到桌面 4.在桌面用记事本打开复制过来的hosts 5.在末尾加上一行&#xff0c;IP写刚才复制的 6.复制桌面的hosts,粘贴回C:\Window…

剑指offer48.最长不含重复字符的子字符串

我一开始的想法是创建一个大小为26的int数组&#xff0c;下标为0对应的是‘a&#xff0c;25对应的是’z&#xff0c;然后一开始都赋为-1&#xff0c;用一个for循环从头遍历这个字符串&#xff0c;通过char c s.charAt(i)获得字符&#xff0c;然后c-97&#xff0c;就是它对应的…

windows系统之WSL 安装 Ubuntu

WSL windows10 以上才有这个wsl功能 WSL&#xff1a; windows Subsystem for Linux 是应用于Windows系统之上的Linux子系统 作用很简单&#xff0c;可以在Windows系统中获取Linux系统环境&#xff0c;并完全直连计算机硬件&#xff0c;无需要通过虚拟机虚拟硬件 Windows10的W…

swift - 如何在数组大小更改后刷新 ForEach 显示元素的数量(SwiftUI、Xcode 11 Beta 5)

我正在尝试实现一个 View &#xff0c;该 View 可以在内容数组的大小发生变化时更改显示项目的数量(由 ForEach 循环创建)&#xff0c;就像购物应用程序可能会在用户下拉刷新后更改其可用项目的数量一样 这是我到目前为止尝试过的一些代码。如果我没记错的话&#xff0c;这些适…

解决SVN或GIT忽略提交文件的问题

背景 使用IDEA 的SVN插件提交文件是总是会提交一些不需要提交的文件; 我们可以通过一些简单设置忽略这些文件。 git 在项目根目录新建文本文件&#xff0c;修改后缀为.gitignore 文件中添加内容 *.iml .project .gradle/ .idea/ target/ build/ .vscode/ .settings/ .facto…

matlab进阶:求解在约束条件下的多元目标函数最值(fmincon函数详解)

&#x1f305;*&#x1f539;** φ(゜▽゜*)♪ **&#x1f539;*&#x1f305; 欢迎来到馒头侠的博客&#xff0c;该类目主要讲数学建模的知识&#xff0c;大家一起学习&#xff0c;联系最后的横幅&#xff01; 喜欢的朋友可以关注下&#xff0c;私信下次更新不迷路&#xff0…

MySQL数据库备份与恢复

在任何数据库环境中&#xff0c;总会有不确定的意外情况发生&#xff0c;比如停电&#xff0c;计算机系统的各种软硬件故障&#xff0c;认为破坏&#xff0c;管理员误操作等是不可避免的&#xff0c;这些情况可能会导致 数据的丢失&#xff0c; 服务器瘫痪 等严重后果。存在多个…

Linux第一个小程序-进度条(缓冲区概念)

1.\r和\n C语言中有很多字符 a.可显字符 b.控制字符 对于回车其实有两个动作&#xff0c;首先换行&#xff0c;在将光标指向最左侧 \r &#xff1a;回车 \n&#xff1a;换行 下面举个例子&#xff1a; 把\n去掉会怎样 什么都没输出。为什么&#xff1f; 2.缓冲区概念 观察下两个…