• 数组是一种映射关系,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内元素

  1. 通过下标访问:
  • 类似普通数组的访问方式
  • 如访问​​map<char,int> mp​​​,写​​mp['a']​
  1. 通过迭代器访问
  • 定义迭代器​​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
*/

三、常用操作

  • 设有map容器mp

操作

代码

时间复杂度

说明

查找键为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数组用
  • 也可能有字符串到字符串间的映射
  • 注意:
  1. map的键和值是唯一对应的,如果要一个键对应多个值,只能用​​multimap​
  2. C++ 11中增加了​​unordered_map​​,以散列代替了map内部的红黑树,对于只建立映射而不要求按键排序的场合,用这个比map快很多