map 是 key-value 构成的集合。
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;初始化时必须给 map<> 类模板同时设置key与value的类型模板实参。 实参类型不限于基本类型、类类型(class、struct、union),还可以是容器模板。
a.只能前面的键找后面的数值;后面的找前面的返回空字符;
cout << fruits["香蕉"] <<endl; //a.只能前面的键找后面的数值; cout << fruits["banana"] <<endl; //a.后面的找前面的返回空字符;b.找到了返回内容,找不到返回空字符;可以用if判断
if(fruits.count("香蕉")==1){ //b.找到了返回内容,找不到返回空字符;,可以用if判断 cout << fruits["香蕉"] <<endl; } 完整案例 #include <iostream> #include <map> using namespace std; int main() { map<string,string> fruits ={ {"香蕉","banana"}, {"苹果","apple"}, {"橘子","orange"} }; for(auto p: fruits){ //c++11的常见用法; cout << p.first <<"\t" << p.second << endl; } cout << fruits["香蕉"] <<endl; //a.只能前面的键找后面的; cout << fruits["banana"] <<endl; //a.后面的找前面的返回空字符; if(fruits.count("香蕉")==1){ //b.找到了返回内容,找不到返回空字符;,可以用if判断 cout << fruits["香蕉"] <<endl; } return 0; }a.遍历常见的用法
for(auto p: fruits){ //c++11的常见用法; cout << p.first <<"\t" << p.second << endl; }b.删除:通过删除键来删除键值对
fruits.erase("香蕉");c.插入:(法1)pair()通过类型插入键值对; (法2:常用)make_pair()直接添加键值对
fruits.insert(pair<string,string>("樱桃","cherry"));//c1.pair()通过类型插入键值对; fruits.insert(make_pair("梨子","pear"));//c2.make_pair()直接添加键值对d.修改:通过修改值来修改键值对
fruits["橘子"] = "juice"; //d.修改:通过修改值来修改键值对 完整案例 #include <iostream> #include <map> using namespace std; int main() { map<string,string> fruits ={ {"香蕉","banana"}, {"苹果","apple"}, {"橘子","orange"} }; fruits.erase("香蕉"); //b.删除:通过删除键来删除键值对 for(auto p: fruits){ //a.c++11的常见遍历用法; cout << p.first <<"\t" << p.second << endl; } cout << endl; fruits["橘子"] = "juice"; //d.修改:通过修改值来修改键值对 fruits.insert(pair<string,string>("樱桃","cherry"));//c1.pair()通过类型插入键值对; fruits.insert(make_pair("梨子","pear"));//c2.make_pair()直接添加键值对 for(auto p: fruits){ //c++11的常见用法; cout << p.first <<"\t" << p.second << endl; } cout << endl; map<string,string>::iterator it = fruits.find("苹果"); if(it != fruits.end()){ cout << it ->first << it->second << endl; } return 0; }数字和出现的次数
step1. 键值对表示<数字,次数>,首先遍历向量nums,将其存入map; 空值插入1;非空的话,次数自增
map<int,int> m; //a.键值对表示<数字,次数> for(auto n:nums){ //b1.首先遍历向量nums,将其存入map if(m.count(n)==0){ m.insert(make_pair(n,1));//b2.空值插入1 }else{ ++m[n]; //b3.非空的话,次数自增 }step2 遍历map,次数为1的将键存入到vector
for(auto p:m){ //c.遍历map,次数为1的将键存入到vector if(p.second == 1){ res.push_back(p.first); } } 完整代码 #include <iostream> #include <map> #include <vector> using namespace std; vector<int> timesNumbers(vector<int>& nums){ map<int,int> m; //a.键值对表示<数字,次数> for(auto n:nums){ //b1.首先遍历向量nums,将其存入map if(m.count(n)==0){ m.insert(make_pair(n,1));//b2.空值插入1 }else{ ++m[n]; //b3.非空的话,次数自增 } } vector<int> res; for(auto p:m){ //c.遍历map,次数为1的将键存入到vector if(p.second == 1){ res.push_back(p.first); } } return res; } int main() { vector<int> vec = {4,1,4,6}; vector<int> res = timesNumbers(vec); for(auto n:res){ cout << n << "\t"; } cout << endl; return 0; }数字出现的次数 step1. 键值对表示<数字,次数>,首先遍历向量nums,将其存入map; 空值插入1;非空的话,次数自增
map<int,int> m; //a.键值对表示<数字,次数> for(auto n:nums){ //b1.首先遍历向量nums,将其存入map if(m.count(n)==0){ m.insert(make_pair(n,1));//b2.空值插入1 }else{ ++m[n]; //b3.非空的话,次数自增 }step2. 遍历nums,将次数为1的键返回;
for(auto p:m){ //c.将次数为1的键返回; if(p.second == 1){ res=p.first; } } return res; } 完整代码 int singleNumber(vector<int>& nums) { map<int,int> m; //a.键值对表示<数字,次数> for(auto n:nums){ //b1.首先遍历向量nums,将其存入map if(m.count(n)==0){ m.insert(make_pair(n,1));//b2.空值插入1 }else{ ++m[n]; //b3.非空的话,次数自增 } } int res; for(auto p:m){ //c.遍历nums,将次数为1的键返回; if(p.second == 1){ res=p.first; } } return res; }3.标准
迭代器 迭代器作用c.begin()头迭代器c.end()尾迭代器c.rbegin()反向头迭代器c.rend()反向尾迭代器与vector相似。
数据量操作 函数作用c.size()大小c.max_size()最大大小c.empty()判空c.clear()清空说明:
map只有在访问key,如果key不存在则会创建,反之,使用已存在的<key,val>。对于已存在的key,insert()操作是无法插入数据,可以通过判断insert()的返回值pair<map<>::iterator,bool>,得知是否插入成功。 vector为空,是否可以使用下标运算符添加数据?例如:vec[2]=3;执行for_each
for_each(m.begin(),m.end(),Display); C++11auto迭代器写法 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; });如果key不存在,默认创建。
默认按照key升序排列。自定义排序是,可以在实例化加上key的comp仿函数,重载<运算符。
map<key类型,value类型,comp> m;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; }); 把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互换