头文件:#include<map>
,固然,万能库就不用我多说了吧。。算法
介绍:map容器是一个键 (key) 到值 (value) 的映射。由于重载了 [ ] 运算符,map像是数组的“高级版”。map的key和value能够是任意类型,其中key必须定义“小于号”运算符。例如能够用一个map <string,int> month_name
来表示“月份名字到月份编号”的映射,而后用month_name["July"]=7;
这样的方式来赋值。数组
声明:函数
map<key_type,value_type>name;
例如:code
map<long long,bool>vis; map<string,int>hash; map<pair<int,int>,vector<int>>test;
在不少时候,map容器被看成Hash表使用,创建从复杂信息key(如字符串)到简单信息 value(如必定范围内的整数)的映射。 由于map基于平衡树实现,因此它的大部分操做的时间复杂度都在$O(log n)$级别,略慢于使用 Hash函数实现的传统Hash表。从C++11开始,STL中新增了 unordered_map 等基于Hash的容器,但部分算法竞赛并不支持C++11标准,这里就再也不介绍这些新容器。rem
size/empty/clear/begin/end 与set相似,分别为元素个数、是否为空、清空、首迭代器、尾迭代器。字符串
迭代器 map 的迭代器和 set 同样,也是“双向访问迭代器”。对 map 的迭代器解除引用后,将获得一个二元组 pair<key_type,value_type>
。string
insert/erase 与set相似,分别为插入、删除。insert的参数是pair<key_type,value_type>
,erase的参数能够是pair或者迭代器。hash
map<int,int > h; h.insert(make_pair(1,2)),h.insert(make_pair(2,3)); map<int,int > :: iterator it=h.begin(); pair<int,int > p=*it; h.erase(it),h.erase(make_pair(2,3)); cout<<p.first<<' '<<p.second<<endl;
find h.find(x) 在变量名为h 的map 中查找key 为 x 的二元组,并返回指向改二元组的迭代器。若不存在,返回h.end()。时间复杂度为 $O(log n)$。it
[ ] 操做符 h[key]返回key映射到的value的引用,时间复杂度为$O(log n)$。 [ ]操做符是map最吸引人的地方。咱们能够很方便地经过 h[key] 来获得 key 对应的value,还能够对 h[key] 进行赋值操做,改变key对应的value。 须要特别注意的是,若查找的key不存在,则执行 h[key] 后,h会自动新建一个二元组(key,zero),并返回zero的引用。这里zero表示一个广义“零值”,如整数0、空字符串等。若是查找后不对 h[key] 进行赋值,那么时间一长,h 会包含不少无用的“零值二元组”,白白地占用了空间,下降了程序运行效率。强烈建议读者在用 [ ] 操做符查询以前,先用 find 方法检查 key 的存在性。class
[实例] 用map统计字符串出现的次数 给定 n 个字符串,m 个问题,每一个问题询问一个字符串出现的次数。 n<=20000,m<=20000,每一个字符串的长度都不超过20.
map<string,int> h; char str[25]; for(int i=1;i<=n;i++){ scanf("%s",str); h[str]++; } for(int i=1;i<=m;i++){ scanf("%s",str); if(h.find(str)==h.end())puts("0"); else printf("%d\n",h[str]); }
提示: set头文件中的set和map头文件中的map分别是集合和映射。两者都支持insert、find、count和remove操做,而且能够按照从小到大的顺序循环遍历其中的元素。map还提供了“[ ]”运算符,使得 map 能够像数组同样使用。事实上,map 也称为“关联数组”。