map映照容的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。
map映照容器的数据结构也是采用红黑树来实现的,插入元素的键值不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。由于map与set采用的都是红黑树的数据结构,所以,用法基本相似。
映照数据 |
键值 |
Name Score
Jack 98.5
Bomi 96.0
Kate 97.5
使用map容器需要头文件包含语句"#include<map>"
一.map创建、元素插入与遍历访问
创建map对象,键值与映照数据的类型由自己定义。在没有指定比较函数时,元素的插入位置是按键值由大到小插入到黑白树中去的,这点与set一样。
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 map<string,float> m; 8 m["Jack"]=98.5; 9 m["Bomi"]=96.0; 10 m["Kate"]=97.5; 11 map<string,float>::iterator it; 12 for(it=m.begin();it!=m.end();it++) 13 { 14 cout<<(*it).first<<":"<<(*it).second<<endl; 15 } 16 return 0; 17 }
运行结果
Bomi:96 Jack:98.5 Kate:97.5
二.(1)删除元素:与set容器一样,map映照容器的erase()删除元素函数,可以删除某个迭代器位置上的元素、等于某个键值的元素、一个迭代器区间上的所有元素,当然,也可以使用clear()方法清空map映照容器。
删除键值为28的元素。
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 map<int,char> m; 8 m[25]='m'; 9 m[28]='k'; 10 m[10]='x'; 11 m[30]='a'; 12 m.erase(28); 13 map<int,char>::iterator it; 14 for(it=m.begin();it!=m.end();it++) 15 { 16 cout<<(*it).first<<":"<<(*it).second<<endl; 17 } 18 return 0; 19 }
运行结果
10:x 25:m 30:a
(2)元素反向遍历:可以使用反向迭代器reverse_iterator反向遍历map映照容器中的数据,它需要rbegin()方法和rend()方法指出反向遍历的起始位置和终止位置。
三.自定义比较函数
(1)如果元素不是结构体,其编写比较函数的方法与set一样;
(2)如果元素结构体,直接把比较函数写在结构体内
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 struct Info 6 { 7 string name; 8 float score; 9 bool operator<(const Info &a)const 10 { 11 return a.score<score; //按score由小到大排序,如果要由大到小,使用“>”号即可 12 } 13 }; 14 int main() 15 { 16 map<Info,int> m; 17 Info info; 18 info.name="Jack"; //插入元素,按键值的由小到大放进黑白树 19 info.score=60; 20 m[info]=25; 21 info.name="Bomi"; 22 info.score=80; 23 m[info]=10; 24 info.name="Peti"; 25 info.score=66.5; 26 m[info]=30; 27 map<Info,int>::iterator it; 28 for(it=m.begin();it!=m.end();it++) 29 { 30 cout<<(*it).second<<":"; 31 cout<<((*it).first).name<<" "<<((*it).first).score<<endl; 32 } 33 return 0; 34 }
运行结果
10:Bomi 80 30:Peti 66.5 25:Jack 60
四.用map实现数字分离
对数字的各位进行分离,采用取余等数学方法操作是很耗时的。而把数字当成字符串,使用map的映照功能,很方便地实现了数字分离。下面这个程序将一个字符串中的字符当成数字,并将各位的数值相加,最后输出各位的和。
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 map<char,int> m; 8 m['0']=0; //赋值:字符映照数字,字符只能为一位 9 m['1']=1; 10 m['2']=2; 11 m['3']=3; 12 m['4']=4; 13 m['5']=5; 14 m['6']=6; 15 m['7']=7; 16 m['8']=8; 17 m['9']=9; 18 /*上面的10条赋值语句可采用下面这个循环来简化代码编写 19 for(int j=0;j<10;j++) 20 { 21 m['0'+j]=j; 22 } 23 */ 24 string sa; 25 sa="6234"; 26 int sum=0; 27 for(int i=0;i<sa.length();i++) 28 { 29 sum+=m[sa[i]]; 30 } 31 cout<<sum<<endl; 32 return 0; 33 }
运行结果
15
五.数字映照字符的map方法
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 map<int,char> m; 8 m[0]='0'; //赋值:字符映照数字 9 m[1]='1'; 10 m[2]='2'; 11 m[3]='3'; 12 m[4]='4'; 13 m[5]='5'; 14 m[6]='6'; 15 m[7]='7'; 16 m[8]='8'; 17 m[9]='9'; 18 /*上面的10条赋值语句可采用下面这个循环来简化代码编写 19 for(int j=0;j<10;j++) 20 { 21 m['0'+j]=j; 22 } 23 */ 24 int n=7; 25 cout<<m[n]<<endl; 26 return 0; 27 }
运行结果
7
multimap多重映照容器
multimap与map基本相同,唯独不同的是,multimap允许插入重复键值的元素。由于允许重复键值的存在,所以,multimap的元素插入,删除,查找与map不同。
multimap对象创建、元素插入
可以重复插入元素,插入元素需要使用insert()方法
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 multimap<string,double> m; 8 m.insert(pair<string,double>("Jack",300.5)); 9 m.insert(pair<string,double>("Kity",200)); 10 m.insert(pair<string,double>("Memi",500)); 11 m.insert(pair<string,double>("Jack",306)); 12 multimap<string,double>::iterator it; 13 for(it=m.begin();it!=m.end();it++) 14 { 15 cout<<(*it).first<<":"<<(*it).second<<endl; 16 } 17 return 0; 18 }
运行结果
Jack:300.5 Jack:306 Kity:200 Memi:500