[C++STL教程]4.map超强的容器,它终于来了!零基础都能理解的入门教程
之前我们介绍过vector
, queue
, stack
,他们都有一个共同的特点,就是都可以用线性表来模拟。今天我们来学习一个全新且高封装性的容器:map
。
作者:Eriktse
简介:19岁,211计算机在读,现役ACM银牌选手力争以通俗易懂的方式讲解算法!️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)
个人博客:www.eriktse.com
什么是 map
std::map
是C++标准库中的一个容器,数据以<key, value>
的形式存储,也就是我们常说的“键值对”形式,且其“键值对”是有序的,也就是可以顺序遍历的。
这意味着一个key
只能对应一个value
,而一个value
可能对应了多个key
,其关系有点像高中学过的函数的关系。
map
的底层一般实现为红黑树
,这个仅作了解即可。搜索、移除和插入操作拥有log级别复杂度。
初始化 map
首先引入头文件:
#include <map>
用以下代码声明一个空的map
:
map<int, string> mp;//声明一个类型为<int, string>的map
注意这里使用了string
,也就需要引入头文件#include <string>
。
插入数据
map
有一个函数是insert()
,支持将数据插入。时间复杂度O(logn)
,n为map中已有的数据个数。
mp.insert({0, "张三"});//插入一条数据
当然还有另外一种办法来插入数据,就是直接赋值,像操作数组一样操作map
,但是这个map
的下标可不是连续的,可以是任意符合条件的key
。
mp[2] = "李四";
//现在map中的数据:{0: "张三", 2: "李四"}
可能会有小伙伴疑惑,这里没有1的吗?在这里map
的key
只要int
类型即可,就算是负数都可以!
mp[-1] = "王五";
//mp = {-1: "王五", 0: "张三", 2: "李四"};
mp[-1] = "eriktse";
//mp = {-1: "eriktse", 0: "张三", 2: "李四"};
值得注意的是,value
是可覆盖的,且这里的key
是有序的,虽然我的-1
这个key
是后面加入的,但是却排在了第一个,如果顺序遍历这个mp
的话,{-1: "eriktse"}
会是第一个被遍历到的。后面会讲到如何遍历map
。
删除数据 & 清空map
erase(key)
方法:删除key
所对应的数据。时间复杂度O(logn)
。
clear()
方法:清空整个map。
mp.earse(-1);
////mp = {0: "张三", 2: "李四"};
获取map大小(元素个数)
size()
方法:返回map的大小,是一个非负整数。
检查容器是否无元素,即是否 begin() == end()
。
获取map中的数据
直接像用数组一样获取就行了。
mp[key]
表示map
中这个key
所对应的value
。
cout << mp[0] << '\n';//输出: 张三
遍历输出map
遍历map需要用到std::iterator
迭代器,没有接触过的同学可能不太了解,可以先看代码,或者用第二种方法。
方法一:迭代器法
void print(map<int, string> mp)
{
cout << '{';
for(map<int, string>::iterator it = mp.begin(); it != mp.end(); ++ it)
{
cout << i.first << ": " << "\"" << i.second << "\"";
if(next(it) != mp.end())cout << ", ";//这里的next(it)表示it的下一个位置,注意这里不能用 + 1运算,会报错
}
cout << '}';
}
在需要输出map的地方调用print(mp)
即可。
方法二:auto
关键字
void print(map<int, string> mp)
{
cout << '{';
for(auto &i : mp)
{
cout << i.first << ": " << "\"" << i.second << "\"";
if(i != *mp.rbegin())cout << ", ";
}
cout << '}';
}
关于auto关键字,在这篇文章末尾有简单介绍:https://www.eriktse.com/algorithm/1051.html
判断某个key是否存在
count(key)
可以返回key
出现的次数,但是在经典的map
中一个key
只能出现一次,所以当返回值为1
时说明key
存在,返回值为0
说明key
不存在。时间复杂度O(logn)
。
在容器
multimap
中一个key
允许出现多次。
还可用find()
函数判断。
find(key)
返回一个迭代器表示找到的数据项,当找不到时返回end()
。
if(mp.count(x))cout << "mp中存在key == x的项";
else cout << "mp中不存在key == x的项";
if(mp.find(x) != mp.end())cout << "mp中存在key == x的项";
else cout << "mp中不存在key == x的项";
swap方法
mp1.swap(mp2)
方法:交换两个map
容器。
看下面这个例子:
map<int, string> mp1, mp2;//声明一个类型为<int, string>的map
mp1.insert({0, "张三"});//插入一条数据
mp1[2] = "李四";
mp1[-1] = "eriktse";
mp2[5] = "A";
mp1.swap(mp2);
//print函数需要自己实现
print(mp1);//输出: {5: "A"}
总结
map
是C++中常用的stl之一,也是算法竞赛中的常客,大家一定要牢牢记住map
的用法、
本文由eriktse原创,创作不易,如果对您有帮助,欢迎小伙伴们点赞、收藏、留言
[C++STL教程]4.map超强的容器,它终于来了!零基础都能理解的入门教程的更多相关文章
- 【零基础】Selenium:Webdriver图文入门教程java篇(附相关包下载)
一.selenium2.0简述 与一般的浏览器测试框架(爬虫框架)不同,Selenium2.0实际上由两个部分组成Selenium+webdriver,Selenium负责用户指令的解释(code), ...
- 🚴♂️全套MySQL数据库教程_Mysql基础入门教程,零基础小白自学MySQL数据库必备教程☔ #002 # 第二单元 MySQL数据类型、操作表#
二.本单元知识点概述 (Ⅰ)知识点概述 二.本单元教学目标 (Ⅰ)重点知识目标 1.Mysql的数据类型2.如何选择数据类型3.创建表4.修改表5.删除表 (Ⅱ)能力目标 1.熟练创建数据库及删除数据 ...
- ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区
原文:ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区 1 用ArcMap制作地图 作为ArcGIS for Deskto ...
- Docker入门教程(三)Dockerfile
Docker入门教程(三)Dockerfile [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第三篇,介绍了Dockerfile的语法,DockerOn ...
- Docker入门教程(二)命令
Docker入门教程(二)命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第二篇,介绍了Docker的基本命令以及命令的用法和功能. 在Docker ...
- Docker入门教程(一)介绍
http://dockone.io/article/101 Docker入门教程(一)介绍 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第一篇,介绍了 ...
- 【知识整理】这可能是最好的RxJava 2.x 入门教程(二)
这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) GitHub 代码同步更新:https://github.com/nanchen22 ...
- 【知识整理】这可能是最好的RxJava 2.x 入门教程(五)
这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) 这可能是最好的RxJava 2.x 入门教程(二) 这可能是最好的RxJava 2. ...
- 基于Spring Cloud的微服务入门教程
(本教程的原地址发布在本人的简书上:http://www.jianshu.com/p/947d57d042e7,若各位看官有什么问题或不同看法请在这里或简书留言,谢谢!) 本人也是前段时间才开始接触S ...
- React实例入门教程(1)基础API,JSX语法--hello world
前 言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发 ...
随机推荐
- iOS用runtime给一个类动态添加方法 ---class_addMethod
先介绍下class_addMethod这个fangfa /** * Adds a new method to a class with a given name and implementat ...
- CSS选择符及盒模型
一.选择符 1.类型选择符(标签选择符) 特点:能选中当前结构里面(全部同名)标签. 应用:统一某一标签样式时或清除某一标签默认样式时. 2.id选择符 特点:(唯一性!)在同一个页面里面,一个id名 ...
- 微信小程序:流程/步骤流/时间轴自定义组件
效果图: 1.首先在小程序components目录下新建一个名为step的文件夹,再建step组件名.结构如下. 直接上代码 step.wxml <view class="step&q ...
- lua按某些键排序的方法
function sort(list, ...) local opts = {...}; local len = #opts; return table.sort(list, function(a, ...
- h5移动端识别二维码信息
jsqr插件 图片跨域时不允许绘制到canvas,所以先转blob在画到canvas上面就可以,如果不跨域直接画就行 function getImageBlob (url) { ...
- Linux CentOS Docker 安装、加载配置
Docker Version:2.10.2 OS: CentOS 7 1.卸载 $ sudo yum remove docker \ docker-client \ docker-client-lat ...
- go语言读取文件的简单使用
注意:打开文件记得一定要关闭 file, err := os.Open("文件名称") defer file.Close() 一.打开文件 1. file, err := os.O ...
- Promise 一些注意点
Promise是一个构造函数,其身上有all.race.resolve.reject这些方法,都可以通过 Promise. 调用. 注意点1 Promise构造函数接受一个参数 => funct ...
- VS中多字节字符集和UNICODE字符集的使用说明
两者的核心区别: 1.在制作多国语言软件时,使用Unicode(UTF-16,16bits,两个字节).无特殊要求时,还是使用多字节字符集比较好. 2.如果要兼容C编程,只能使用多字节字符集.这里的兼 ...
- SpringCloud之旅
现在大部分公司的项目架构都选择了微服务,我们公司也不例外,那么什么是微服务呢?今天就来开启SpringCloud之旅! SpringCloud是基于SpringBoot的一整套的微服务架构.他提供了微 ...