~map && pair~
map 和 pair 同样属于一种不是特别常用的的STL容器,
但确实比 set 常用得多
两者都是有两个关键字的STL
且可以将 pair 类型插入 map 中
又或者说 map 就是由一堆 pair 组成的
且这些 pair 所表示的两个数据类型分别相同
类似于变量和数组的关系
map 对象是模板类,需要关键字和储存对象两个模板参数
它可以将不同的数据类型链接起来
比如可以把“student1”作为一个数组元素的下标来访问这个元素的值
看起来功能很强大(大雾
那现在让我们来康康 map 和 pair 到底怎么使用叭。
map 可以理解为一个功能更加 NB(时间和空间也更大)的二维数组(其实里面装的是一棵红黑树),而且这颗红黑树内部具有对数据自动排序的特点,常数也在可以接受的范围内
它的功能主要是可以连接不同的数据类型
比如字符串 -> 整形,结构体 -> 浮点数,甚至还可能有 map -> set
听起来难以理解对吧,
那好,让我们举个例子
首先看一下如何定义一个 map
先是祖传操作:STL 调用库
//STL容器祖传操作了
#include <map>
#include <string>
#include <iostream>
#include <cstdio>
//可别光include<map>,map所需两种数据类型也要调用
using namespace std;
map<int, string>stdname;
int main()
{
}
这样就声明了一个 int->string 的 map 了
其实就是一个用 int 做引索,指向一个 string 类的指针
祖传下一步:插入元素
就像一张图中的一条边一样(大概是无权图吧
map 中的元素是有联系的
那我们这里介绍一下表示 map 中关系的一种数据类型
就是刚才讲到的 pair(<map>中就包含了 pair 的头文件 < utility > ,所以无需再写
pair 中只包含两个元素:first 和 second
两个元素的数据类型可以不同
定义 pair 的方式与 map 几乎无差:
#include <map>
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int main()
{
pair<string,int> student1;
student1.first = "Jxc";
student1.second = 150;
cout<<student1.first<<" "<<student1.second<<endl;
return 0;
}
输出结果是
Jxc 150
看起来很好理解叭
你也可以将 pair 看成一个只能含有两个元素的结构体
事实上确实如此
而且 pair 单独拿出来用很可能比结构体还难受
不过不要忘了我们本文真正的主角— map
通常情况下(其实用的不算太多
pair 一直是作为插入 map 的工具(中间商?赚常数(大雾))而存在的
对于两个已有的对象,可以使用 make_pair 命令将两个元素合成一个 pair
int a = 8;
string m = "James";
pair<int, string> newone;
newone = makepair(a, m);
可以对 map 使用 insert 命令来插入一个 pair,前提是 pair 的两个数据类型分别与 map 所需要的数据类型相同
看一下如何插入一个 pair 到一个 map 中去
map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, "student_one"));
mapStudent.insert(pair<int, string>(2, "student_two"));
mapStudent.insert(pair<int, string>(3, "student_three"));
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
分析一下这段代码
其实就是在 insert 命令中声明了 3 个不同的(但是两个元素类型分别相同的pair)
然后将其插入名为 mapStudent 的 map 中
建立起了三个一一映射
这里要记住
一个关键词只能对应一个储存对象,而一个储存对象可以由多个关键词指向
跟其他 STL 容器一样
祖传函数size, empty, clear, begin, end等用法都大差不差
这里也不再过多做介绍
STL 中祖传的迭代器也在 map 中得以实现
和 set 一样都为双向访问迭代器
支持读和写以及自增和自减运算
声明方式依然是 STL 祖传的 iterator
map<int, int> :: iterator it = mp.begin( );
除了刚才提到的 insert 命令(这货只能插入 pair)
erase 函数也可以用来进行插入操作
比 insert 更强的是 erase 可以通过迭代器进行插入,也可以直接插入 pair
用法也与其他 STL 大差不差
最后压轴的是 find 函数
find( x ) 可以通过 x 查找 map 中第二个类型(key)与之对应的一个二元组并返回其迭代器
重头戏终于要来了
map 最 nb 最吸引人的地方
是 map 可以使用[ ]进行访问
哦你问我[ ]这货是啥?咋用?
哇老哥,你还没用过数组嘛
没想到吧,map 可以像数组一样进行访问
类似于可以用字符串当下标来访问元素
和数组一样,map 也可以通过数组下标来进行数据修改与加和
类似 mp[student1] = 150;这样的神奇操作
可以实现快速的一一对应,有时还可以用来做 hash
我们依此可以很方便地通过 key 找到 value
特别的是
如果没有这个 key 也就是查找不到的话
map 中会自动新建一个 pair 储存 (key, zero)
这里的 zero 表示的是广义的0
可以是空字符,数字0,空串等等等等
长此以往会占据大量空间
所以建议使用[ ]前先 find 一下看看有没有这个二元组以避免空间冗余
~END~