【C++/STL】4. map映射
原创
©著作权归作者所有:来自51CTO博客作者云端FFF的原创作品,请联系作者获取转载授权,否则将追究法律责任
- 数组是一种映射关系,int型数组把int映射到int,double型数组把double映射到double。用map可以构建任意类型到任意类型的数组,包括任意基本类型和STL容器
- 考虑这个情境:要在某个文件中判断一些给定的数字是否出现过,按正常思路,可以开一个bool型数组bool hashTable[max_size]来记录对应数字出现与否,但如果数字特别大(如有几千位),这个数组就会开不了。这时可以用map来解决,先把数字转成字符串,再建立string到int的map映射即可
- map内部使用红黑树实现,所以在建立映射的过程中会自动按键从小到大排序
- map定义于
map.h
,命名空间std
一、构造函数
- 注意:要构造字符串相关的映射,必须用
string
,char
数组不能用作键值
作用
| 代码
| 说明
|
定义一个map
| map<typename1,typename2> mp;
| 前一个是键的类型,后一个是值的类型
|
map<string,int> mp1; //string -> int
map<set<int>,string> mp2; //set<int> -> string
二、访问map内元素
- 通过下标访问:
- 类似普通数组的访问方式
- 如访问
map<char,int> mp
,写mp['a']
- 通过迭代器访问
- 定义迭代器
map<typename1,typename2>:: iterator it
- 访问键
it->first
,访问值it->second
#include <iostream>
#include <map>
using namespace std;
void printMap(map<char,int> *mp)
{
for(map<char,int>::iterator it = mp->begin();it!=mp->end();it++)
printf("%c %d\n",it->first,it->second);
}
int main()
{
map<char,int> mp;
mp['a'] = 3;
mp['b'] = 2;
mp['c'] = 1;
cout<<mp['a']<<mp['b']<<mp['c']<<endl;
printMap(&mp);
return 0;
}
/*
321
a 3
b 2
c 1
*/
三、常用操作
操作
| 代码
| 时间复杂度
| 说明
|
查找键为key的元素
| mp.find(key)
| O(logN),N为map中映射个数
| 返回一个map迭代器,如果没找到,返回mp.end()
|
删除迭代器it对应的元素
| mp.erase(it)
| O(1)
| 可以结合find操作使用
|
删除键为key的元素
| mp.erase(key)
| O(logN),N为set中元素个数
| -
|
删除两个迭代器范围内的元素
| mp.erase(first,last)
| O(last-first)
| 删除[first,last)区间元素
|
获得set内元素个数
| st.size()
| O(1)
| -
|
清空set内元素
| st.clear()
| O(N),N为set中元素个数
| -
|
#include <iostream>
#include <map>
using namespace std;
#define KeyInMap(mp,key) cout<<"键"<<key<<"在map中吗:"<<!(mp.find(key)==mp.end()) <<endl;
void printMap(map<char,int> *mp)
{
for(map<char,int>::iterator it = mp->begin();it!=mp->end();it++)
printf("%c %d\n",it->first,it->second);
cout<<endl;
}
int main()
{
map<char,int> mp;
mp['a'] = 8;
mp['b'] = 7;
mp['c'] = 6;
mp['d'] = 5;
mp['e'] = 4;
mp['f'] = 3;
mp['g'] = 2;
mp['h'] = 1;
printMap(&mp);
KeyInMap(mp,'a');
map<char,int>::iterator it = mp.find('a'); //find方法
cout<<endl<<"查找键'a':";
cout<<it->first<<" "<<it->second<<endl;
cout<<endl<<"删除键'a'"<<endl; //erase(iterator)方法
mp.erase(it);
KeyInMap(mp,'a');
cout<<endl<<"删除键'b'"<<endl; //erase(key)方法
mp.erase('b');
KeyInMap(mp,'b');
cout<<endl<<"删除键'c','d','e'"<<endl; //erase(iterator1,iteartor2)方法
map<char,int>::iterator it1,it2;
it1=mp.find('c');
it2=mp.find('f');
mp.erase(it1,it2);
printMap(&mp);
cout<<"map尺寸:"<<mp.size()<<endl; //size()方法
cout<<"清空map:"<<endl;
mp.clear(); //clear()方法
cout<<"map尺寸:"<<mp.size()<<endl;
return 0;
}
/*
a 8
b 7
c 6
d 5
e 4
f 3
g 2
h 1
键a在map中吗:1
查找键'a':a 8
删除键'a'
键a在map中吗:0
删除键'b'
键b在map中吗:0
删除键'c','d','e'
f 3
g 2
h 1
map尺寸:3
清空map:
map尺寸:0
*/
四、常见用途
- 建立 字符/字符串与整数 间的映射关系,减少代码量
- 判断大整数或其他类型数据是否存在,把map当成bool数组用
- 也可能有字符串到字符串间的映射
- 注意:
- map的键和值是唯一对应的,如果要一个键对应多个值,只能用
multimap
- C++ 11中增加了
unordered_map
,以散列代替了map内部的红黑树,对于只建立映射而不要求按键排序的场合,用这个比map快很多