1. 简介
map
是key-value
构成的集合。
2. 操作
map
是键值对<key,value>
构据集合。key
必须唯一。
- 主要用来查找
key
对应value
,要求key
必须是可排序的,必须支持<
比较运算符。 -
map
默认是以key
升序存放键值对<key,value>
数据,比较适合二分查找。
map
内部结构
map
使用pair<key,value>
类模板保存key与value,pair<key,value>
有两个public
成员变量:first
和second
,first
存放key,second
存放value。在map
里面可以使用map<>::value_type
表示pair<key,value>
。
typedef pair<key,value> value_type;
2.1 初始化
- 默认构造(可带参数)
- 复制构造
- 范围赋值构造
初始化时必须给map<>
类模板同时设置key与value的类型模板实参。
实参类型不限于基本类型、类类型(class、struct、union),还可以是容器模板。
2.2 基本操作
- 迭代器
迭代器 | 作用 |
---|---|
c.begin() |
头迭代器 |
c.end() |
尾迭代器 |
c.rbegin() |
反向头迭代器 |
c.rend() |
反向尾迭代器 |
与vector
相似。
- 数据量操作
函数 | 作用 |
---|---|
c.size() |
大小 |
c.max_size() |
最大大小 |
c.empty() |
判空 |
c.clear() |
清空 |
2.3 添加数据
-
insert
插入pair<>
数据
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
cout << val.first <<" " << val.second << endl;
}
int main(){
map<int,int> m;
for(int i=0;i<10;i++){
m.insert(pair<int,int>(i,i*10));
}
for_each(m.begin(),m.end(),Display);
}
-
insert
插入map<>::value_type
数据
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
cout << val.first <<" " << val.second << endl;
}
int main(){
map<int,int> m;
for(int i=0;i<10;i++){
m.insert(map<int,int>::value_type(i,i*10));
}
for_each(m.begin(),m.end(),Display);
}
-
insert
插入make_pair
数据
make_pair
是一个函数模板,类似与如下实现:
template<class K,class V)
inline pair<K,V> make_pair(K const& k,V const& v){
return pair<K,V>(k,v);
}
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
cout << val.first <<" " << val.second << endl;
}
int main(){
map<int,int> m;
for(int i=0;i<10;i++){
m.insert(make_pair(i,i*10));
}
for_each(m.begin(),m.end(),Display);
}
- 下标运算符
[]
添加数据
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
cout << val.first <<" " << val.second << endl;
}
int main(){
map<int,int> m;
for(int i=0;i<10;i++){
m[i] = i*10;
}
for_each(m.begin(),m.end(),Display);
}
说明:
-
map
只有在访问key
,如果key
不存在则会创建,反之,使用已存在的<key,val>
。对于已存在的key
,insert()
操作是无法插入数据,可以通过判断insert()
的返回值pair<map<>::iterator,bool>
,得知是否插入成功。
vector
为空,是否可以使用下标运算符添加数据?例如:vec[2]=3;
2.4 遍历
- 迭代器
for
循环
for(map<int,int>::iterator it = m.begin();it != m.end();it++){
cout << "[" << it->first << "]=" << it->second() << endl;
}
-
for_each()
循环
定义函数指针
inline void Display(map<int,int>::value_type const& val){
cout << "[" << val.first << "]=" << val.second << endl;
}
执行for_each
for_each(m.begin(),m.end(),Display);
- C++11
auto
迭代器写法
for(auto it = m.begin();it != m.end();it++){
cout << "[" << it->first << "]=" << it->second() << endl;
}
- C++11 for-loop-scope迭代器写法
for(auto p : m){
cout << "[" << p.first << "]=" << p.second << endl;
}
- C++11
for_each()
与lamdba表达式
for_each(m.begin(),m.end(),[](map<int,int>::value_type& p){
cout << "[" << p.first << "]=" << p.second << endl;
});
2.5 key
查找
-
count()
判断key
是否存在
if(m.count(key) == 1){
...
}
-
find()
判断key
是否存在以及位置
map<int,int>::iterator it = m.find(key);
if(m.end() != it){
...
}
- 下标运算符
[]
m[key];
如果key
不存在,默认创建。
2.6 区域查找
成员变量 | 作用 |
---|---|
m.lower_bound(key) |
key 下边界 |
m.upper_bound(key) |
key 上边界 |
m.equal_range(key) |
key 上下边界 |
2.7 删除
- 关键字删除
m.erase(key);
- 迭代器删除
m.erase(m.begin());
- 区域删除
m.erase(it_a,it_b);
2.8 排序
默认按照key
升序排列。自定义排序是,可以在实例化加上key
的comp
仿函数,重载<
运算符。
map<key类型,value类型,comp> m;
3. 实例
1.两个数组合并成一个map
#include <iostream>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
cout << "[" << val.first << "]=" << val.second << endl;
}
class MapMaker{
public:
MapMaker(map<int,int>& m):m_(m){}
inline bool operator()(int k,int v){
return m_.insert(make_pair(k,v)).second;
}
private:
map<int,int>& m_;
};
int main(){
map<int,int> m;
int arr1[] = {1,2,1,4,5,2,3,4};
int arr2[] = {19,29,39,49,59,69,79,89};
bool res[8];
transform(arr1,arr1+8,arr2,res,MapMaker(m));
cout<< boolalpha;
copy(res,res+8,ostream_iterator<bool>(cout,","));
cout<< noboolalpha << endl;
for_each(m.begin(),m.end(),Display);
}
在C++11中transform
可以使用lamdba表达式,改写成
transform(arr1,arr1+8,arr2,res,[&m](int k,int v){
return m.insert(make_pair(k,v)).second;
});
2.把map
的key和value各自分解成一个vector
#include <iostream>
#include <algorithm>
#include <iterator> // ostream_iterator
#include <vector>
#include <map>
using namespace std;
// 仿函数
class Spliter{
public:
Spliter(vector<int>& k,vector<int>& v):k_(k),v_(v){}
void operator()(map<int,int>::value_type const& pair){
k_.push_back(pair.first);
v_.push_back(pair.second);
}
private:
vector<int>& k_;
vector<int>& v_;
};
int main () {
map<int,int> m;
for(int i=0;i<10;i++){
m[i] = i*10;
}
vector<int> keys;
vector<int> values;
for_each(m.begin(),m.end(),Spliter(keys,values));
copy(keys.begin(),keys.end(),ostream_iterator<int>(cout,","));
cout << endl;
copy(values.begin(),values.end(),ostream_iterator<int>(cout,","));
return 0;
}
在C++11中for_each
可以使用lamdba表达式,改写成
for_each(m.begin(),m.end(),[&keys,&values](map<int,int>::value_type const& pair){
keys.push_back(pair.first);
values.push_back(pair.second);
});
使用C++11 for-loop-scope语法
for(auto p:m){
keys.push_back(p.first);
values.push_back(p.second);
}
- map的key和value互换