1,map简介

map是STL的一个关联容器,它提供一对一的hash。

  • 第一个可以称为关键字(key),每个关键字只能在map中出现一次;
  • 第二个可能称为该关键字的值(value);

map以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map主要用于资料一对一映射(one-to-one)的情況,map內部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能。在map内部所有的数据都是有序的,后边我们会见识到有序的好处。比如一个班级中,每个学生的学号跟他的姓名就存在著一对一映射的关系。

2,map的功能

自动建立key - value的对应。key 和 value可以是任意你需要的类型,包括自定义类型。

3,使用map

使用map得包含map类所在的头文件

#include <map>  //注意,STL头文件没有扩展名.h

map对象是模板类,需要关键字和存储对象两个模板参数:

std:map<int, string> personnel;

这样就定义了一个用int作为索引,并拥有相关联的指向string的指针.

为了使用方便,可以对模板类进行一下类型定义,

typedef map<int,CString> UDT_MAP_INT_CSTRING;

UDT_MAP_INT_CSTRING enumMap;

4,map的构造函数

map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:

map<int, string> mapStudent;

5,插入元素

// 定义一个map对象
map<int, string> mapStudent;// 第一种 用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));// 第二种 用insert函数插入value_type数据
mapStudent.insert(map<int, string>::value_type(001, "student_one"));// 第三种 用"array"方式插入
mapStudent[123] = "student_first";
mapStudent[456] = "student_second";

以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是不能在插入数据的,但是用数组方式就不同了,它可以覆盖以前该关键字对 应的值,用程序说明如下:

mapStudent.insert(map<int, string>::value_type (001, "student_one"));mapStudent.insert(map<int, string>::value_type (001, "student_two"));

上面这两条语句执行后,map中001这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下

// 构造定义,返回一个pair对象
pair<iterator,bool> insert (const value_type& val);pair<map<int, string>::iterator, bool> Insert_Pair;Insert_Pair = mapStudent.insert(map<int, string>::value_type (001, "student_one"));if(!Insert_Pair.second)cout << ""Error insert new element" << endl;

我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。

6, 查找元素

当所查找的关键key出现时,它返回数据所在对象的位置,如果沒有,返回iter与end函数的值相同。

// find 返回迭代器指向当前查找元素的位置否则返回map::end()位置
iter = mapStudent.find("123");if(iter != mapStudent.end())cout<<"Find, the value is"<<iter->second<<endl;
elsecout<<"Do not Find"<<endl;

7, 刪除与清空元素

//迭代器刪除
iter = mapStudent.find("123");
mapStudent.erase(iter);//用关键字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0//用迭代器范围刪除 : 把整个map清空
mapStudent.erase(mapStudent.begin(), mapStudent.end());
//等同于mapStudent.clear()

8,map的大小

在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

int nSize = mapStudent.size();

 9,map的基本操作函数:

 C++ maps是一种关联式容器,包含“关键字/值”对

     begin()         返回指向map头部的迭代器

     clear()        删除所有元素

     count()         返回指定元素出现的次数

     empty()         如果map为空则返回true

     end()           返回指向map末尾的迭代器

     equal_range()   返回特殊条目的迭代器对

     erase()         删除一个元素

     find()          查找一个元素

     get_allocator() 返回map的配置器

     insert()        插入元素

     key_comp()      返回比较元素key的函数

     lower_bound()   返回键值>=给定元素的第一个位置

     max_size()      返回可以容纳的最大元素个数

     rbegin()        返回一个指向map尾部的逆向迭代器

     rend()          返回一个指向map头部的逆向迭代器

     size()          返回map中元素的个数

     swap()           交换两个map

     upper_bound()    返回键值>给定元素的第一个位置

     value_comp()     返回比较元素value的函数

multimap基本用法

multimap和map的功能类似,就不一一介绍了,下面主要说一下这两者的不同:

1、multimap中的key可以重复

2、multimap中没有重载operator[ ]功能

谈谈unordered_map和map的区别

1、内部实现机理不同

map :map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找、删除,添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉搜索树 (又名儿茶查找树、二叉排序树–特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根结点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。

unordered_map :unordered_map内部实现了一个哈希表 (也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应用)。因此,其元素的排列顺序都是无序的。哈表的概念见:详谈哈希表。

2、谈谈各自的优缺点

  • map
  • 1、优点:

        (1)有序性,这是map结构最大的有点,其元素的有序性在很多应用中都会简化很多的操作。

        (2)红黑树,内部实现一个红黑树使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高。

    2、缺点:空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间。

    3、适用处:对于那些有顺序要求的问题,用map会更高效一些。

  • unordered_map
  • 1、优点:因为内部实现了哈希表,因此其查找速度非常的快。

    2、缺点:哈希表的建立比较耗费时间

    3、适用处:对于查找问题,unordered_map 会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

3、总结

1、内存占有率的问题就转化成红黑树 VS Hash表,还是unorder_map占用的内存要高。

2、但是unorder_map执行效率要比map高很多

3、对于unordered_map 或unordered_set 容器,其遍历顺序与创建该容器时输入的顺序不一定相同,因为遍历是按照哈希表从前往后依次遍历的。

unordered_multimap用法

unordered_map 是一个封装哈希表的无序容器。容器中每个元素都是 key/value,每个 key 仅可出现一次。
unordered_multimap 是一个封装哈希表的无序容器。容器中每个元素都是 key/value,每个 key 可重复出现。

unordered_map 和 unordered_multimap 都是基于哈希表实现的,而且冲突策略采用的是链地址法。示意图如下:

操作与unordered_map相似

map,multimap,unordered_map,unordered_multimap的详解相关推荐

  1. 简介明了——map+multimap头文件函数详解

    简介: 只需要记住这些: 1.map函数是一种映射,key–>value 2.map重载了[]运算符,所以可以直接使用 3.map中key值有序且去重(默认升序)   为了更方便.易懂, 笔者将 ...

  2. set/multiset/unordered_set和map/multimap/unordered_map基础汇总

    引言 在STL中,有两种很常见的关联容器,分别是set和map,序列容器的元素是按照在容器中的位置来顺序保存和访问的,而关联容器的元素是按关键元素来保存和访问的.所以关联容器经常用在关键字的查找中,效 ...

  3. sync.Map低层工作原理详解

    sync.Map低层工作原理详解 目录 为什么需要sync.Map?适合什么场景? sync.Map内部实现基本原理及结构体分析 sync.Map低层工作原理 1. 为什么需要sync.Map?适合什 ...

  4. getordefault java_Java map.getOrDefault()方法的用法详解

    Map.getOrDefault(Object key, V defaultValue)方法的作用是: 当Map集合中有这个key时,就使用这个key值: 如果没有就使用默认值defaultValue ...

  5. Pandas数据分析——超好用的Groupby与map、apply、applymap详解

    Groupby详解 在日常的数据分析中,经常需要将数据根据某个(多个)字段划分为不同的群体(group)进行分析,如电商领域将全国的总销售额根据省份进行划分,分析各省销售额的变化情况,社交领域将用户根 ...

  6. c++ map用法_Pandas数据处理三板斧——map、apply、applymap详解

    在日常的数据处理中,经常会对一个DataFrame进行逐行.逐列和逐元素的操作,对应这些操作,Pandas中的map.apply和applymap可以解决绝大部分这样的数据处理需求.这篇文章就以案例附 ...

  7. STL中map和string, vector 用法详解

    1. map 用法详解 std map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成 ...

  8. map函数的用法python,详解Python map函数及Python map()函数的用法

    python map函数 map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list ...

  9. Collection集合类和Map接口各实现类详解

    Java的集合类(collection接口和Map) 一.集合概述 集合:集合是java中提供的一种容器,可以用来存储多个数据. 集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长 ...

  10. C++中的unordered_map常见用法详解

    文章目录 1. std::unordered_map 的定义与特性 2. 构造 std::unordered_map 3. 赋值操作 4. 迭代器操作 4.1 指向整个容器中的元素 4.2 指向某个桶 ...

最新文章

  1. 洛谷 [P1801] 黑匣子
  2. mysqld:表mysql.plugin不存在_PostgreSQL 12.0 表操作
  3. xftp传输文件报错_Xshell+Xftp--Windows平台远程终端解决方案
  4. 数组中两数相加等于特定值,以字符串的形式输出两数角标
  5. mac下面安装mysql
  6. 网络的划分及其Linux下关于网络的命令
  7. soa示例_SOA示例应用程序
  8. [转]Hadoop集群_WordCount运行详解--MapReduce编程模型
  9. Jackson用法详解
  10. python建立文件数据库_python学习-- Django根据现有数据库,自动生成models模型文件...
  11. 关于指针int *p=a和*p=a的纠正
  12. 补习系列(15)-springboot 分布式会话原理
  13. svn外网虚拟服务器设置,svn虚拟服务器设置路由器设置
  14. CS224N笔记(十):问答系统
  15. 云计算:21世纪的商业平台
  16. 给科研新手的论文写作指南
  17. 合唱队形java_动态规划之合唱队形问题
  18. 12306智能刷票,订票
  19. 英华鸿蒙幼儿园一日活动,一日生活常规教研活动——记东升丰乐幼儿园第七次教研活动...
  20. 超级隐蔽的小说阅读器

热门文章

  1. 为Ubuntu Linux安装Docker CE Edge
  2. 上海网域CEO肖确伟:IDC精细化运营探讨
  3. shiro+redis多次调用doReadSession方法的解决方案
  4. Discovering versions from the identity service failed when creating the password plugin.
  5. Jquery插件使用 焦点图插件 MyFocus ,另外记录一款插件 KinMaxShow大背景图插件。...
  6. 实现对现有的aspx请求进行异步队列控制处理
  7. 2021牛客多校7 - xay loves trees(dfs序+主席树-标记永久化)
  8. 洛谷 - P3254 圆桌问题(最大流+路径打印)
  9. XgBoost使用及调参教程
  10. linux命令中提取某一列,怎么用Linux命令提取表格文本中的某列