之前我们介绍过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的吗?在这里mapkey只要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超强的容器,它终于来了!零基础都能理解的入门教程的更多相关文章

  1. 【零基础】Selenium:Webdriver图文入门教程java篇(附相关包下载)

    一.selenium2.0简述 与一般的浏览器测试框架(爬虫框架)不同,Selenium2.0实际上由两个部分组成Selenium+webdriver,Selenium负责用户指令的解释(code), ...

  2. 🚴‍♂️全套MySQL数据库教程_Mysql基础入门教程,零基础小白自学MySQL数据库必备教程☔ #002 # 第二单元 MySQL数据类型、操作表#

    二.本单元知识点概述 (Ⅰ)知识点概述 二.本单元教学目标 (Ⅰ)重点知识目标 1.Mysql的数据类型2.如何选择数据类型3.创建表4.修改表5.删除表 (Ⅱ)能力目标 1.熟练创建数据库及删除数据 ...

  3. ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区 1 用ArcMap制作地图 作为ArcGIS for Deskto ...

  4. Docker入门教程(三)Dockerfile

    Docker入门教程(三)Dockerfile [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第三篇,介绍了Dockerfile的语法,DockerOn ...

  5. Docker入门教程(二)命令

    Docker入门教程(二)命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第二篇,介绍了Docker的基本命令以及命令的用法和功能. 在Docker ...

  6. Docker入门教程(一)介绍

    http://dockone.io/article/101 Docker入门教程(一)介绍 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第一篇,介绍了 ...

  7. 【知识整理】这可能是最好的RxJava 2.x 入门教程(二)

    这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) GitHub 代码同步更新:https://github.com/nanchen22 ...

  8. 【知识整理】这可能是最好的RxJava 2.x 入门教程(五)

    这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) 这可能是最好的RxJava 2.x 入门教程(二) 这可能是最好的RxJava 2. ...

  9. 基于Spring Cloud的微服务入门教程

    (本教程的原地址发布在本人的简书上:http://www.jianshu.com/p/947d57d042e7,若各位看官有什么问题或不同看法请在这里或简书留言,谢谢!) 本人也是前段时间才开始接触S ...

  10. React实例入门教程(1)基础API,JSX语法--hello world

      前  言 毫无疑问,react是目前最最热门的框架(没有之一),了解并学习使用React,可以说是现在每个前端工程师都需要的. 在前端领域,一个框架为何会如此之火爆,无外乎两个原因:性能优秀,开发 ...

随机推荐

  1. Postgresql统计所有表的基本信息(如行数、大小等)

    目录 pg_class 记录表和几乎所有具有列或者像表的东西.这包括索引(但还要参见 pg_index ).序列.视图.物化视图.组合类型和TOAST表,参见 relkind .下面,当我们提及所有这 ...

  2. C# core 流、字节、字符串相互转换

    /// <summary> /// 将 Stream 转成 byte[] /// </summary> public byte[] StreamToBytes(Stream s ...

  3. gimp脚本.scm一些心得记录

    gimp的脚本scm一些心得记录 GIMP 2.10 图像处理脚本推荐GIMP使用脚本使得图像处理的功能更加强大,对于一些常见操作可以通过脚本快速实现.GIMP也出来2.10版本了,比前面的2.8相比 ...

  4. 主要的原型设计工具 :Axure RP

    一. Axure RP简介: Axure RP 能帮助网站需求设计者,快捷而简便的创建基于网站构架图的带注释页面示意图.操作流程图.以及交互设计,并可自动生成用于演示的网页文件和规格文件,以提供演示与 ...

  5. python 添加文件模板,默认添加作者时间等必要信息

    1.模板设置 配置路径:Setting-Editor-File and Code Templates-Python-Script 2.示例输入 代码如下(示例): #!/usr/bin/env pyt ...

  6. springboot项目 报错No mapping for GET /css/bootstrap.css,前端无法展示样式

    说来也奇怪,前几天刚写完的项目 写的好好的 现在打开他就加载不了前端的静态资源了 报错No mapping for GET /css/bootstrap.css 解决方法: 新建一个配置类 ,将静态资 ...

  7. Windows下安装多个Redis实例

    1.在Redis 目录下复制redis.windows-service.conf文件,建议命名规则redis.windows-service-port.conf,我们以6380端口为例. 2.打开re ...

  8. 12.15linux学习第十八天

    今天老刘讲了如同天书一般的隐藏章节,第23章使用OpenLDAP部署目录服务,难度太高了.第16章使用Squid部署代理缓存服务 章节概述: 本章首先介绍代理服务的原理以及作用,然后介绍Squid服务 ...

  9. Python笔记(5)——if 语句一:条件测试(Python编程:从入门到实践)

    每条if语句的核心都是一个值为True或False的表达式.Python根据条件测试的值为True还是False来决定是否执行if语句中的代码.如果条件测试的值为True,Python就执行紧跟在if ...

  10. JSP第五周作业

    1.教材p39实验3(听英语) <%@ page language="java" import="java.util.*" pageEncoding=&q ...