详解C++ STL map 容器
详解C++ STL map 容器
本篇随笔简单讲解一下\(C++STL\)中的\(map\)容器的使用方法和使用技巧。
map容器的概念
\(map\)的英语释义是“地图”,但\(map\)容器可和地图没什么关系。\(map\)是“映射容器”,其存储的两个变量构成了一个键值到元素的映射关系。
比如下图:
我们可以根据键值快速地找到这个映射出的数据。
\(map\)容器的内部实现是一棵红黑树(平衡树的一种),因为比较复杂而且与理解并无多大关系,所以不予介绍,有兴趣的读者可以自己查阅相关的资料。
map容器的声明
\(map\)容器存在于\(STL\)模板库#include<map>
中。使用的时候需要先开这个库。
比如:
#include<map>
map<int,char> mp;
这就建立了一个从一个整型变量到一个字符型变量的映射。
map容器的用法
因为\(map\)容器和\(set\)容器都是使用红黑树作为内部结构实现的。所以其用法比较相似。但由于二者用途大有不同,所以其用途还有微妙的差别。对于初学者来讲,其更容易涉及到的应该是\(vector\)容器、\(queue\)容器等,但是对于大佬们,经常用个\(set\)、\(map\),没事再用\(bitset\)压一压状态这都是家常便饭。
如果有想学习\(set,bitset\)容器的,请参考下面两篇博客,讲的比较详细:
其实,\(C++STL\)容器的使用方式都是差不多的。我们完全可以举一反三地去类比。与\(bitset\)重定义了许多奇形怪状新的函数之外,其他都是大致相同的。所以笔者在此不再做幼稚的介绍,大家都是竞赛狗,应该都能自己看明白。
常规操作
如其他\(C++STL\)容器一样,\(map\)支持基本相同的基本操作:
比如清空操作,函数\(clear()\),返回容器大小\(size()\),返回首尾迭代器\(begin(),end()\)等。
插入操作
\(map\)容器的插入操作大约有两种方法,第一种是类似于数组类型,可以把键值作为数组下标对\(map\)进行直接赋值:
mp[1]='a';
当然,也可以使用\(insert()\)函数进行插入:
mp.insert(map<int,char>::value_type(5,'d'));
删除操作
可以直接用\(erase()\)函数进行删除,如:
mp.erase('b');
遍历操作
和其他容器差不多,\(map\)也是使用迭代器实现遍历的。如果我们要在遍历的时候查询键值(即前面的那个),可以用it->first
来查询,那么,当然也可以用it->second
查询对应值(后面那个)
查找操作
查找操作类比\(set\)的查找操作。但是\(map\)中查找的都是键值。
比如:
mp.find(1);
即查找键值为\(1\)的元素。
map和pair的关系
我们发现,\(map\)和\(C++\)内置二元组\(pair\)特别相似。那是不是\(map\)就是\(pair\)呢?(当然不是)
那么\(map\)和\(pair\)又有什么关系呢?
@JZYShruraK大佬
首先,\(map\)构建的关系是映射,也就是说,如果我们想查询一个键值,那么只会返回唯一的一个对应值。但是如果使用\(pair\)的话,不仅不支持\(O(log)\)级别的查找,也不支持知一求一,因为\(pair\)的第一维可以有很多一样的,也就是说,可能会造成一个键值对应\(n\)多个对应值的情况。这显然不符合映射的概念。