数据之间的转化神器--map

每次比赛的时候,总会出现一两个让我头晕眼花的数据对应题……
每次都感叹:要是有一种数据结构可以完美地表现数据对字符串,字符串对字符串,数据对数据的表示就好了!

于是map出现了。
在那一段光辉的岁月中,我天天用着map,享受它给我带来的快乐。

直到有一天我忘记了怎么使用它。

事到如今,几个月以后的比赛在即,把这个必杀技重新捡起来,是我必做的事!


Map-STL
map内部是用红黑树维持的有序结构。定义:
map<int,string> mapStudent;

一、map的构造

map的构造方法有两种:

1、用 insert 函数插入 pair 数据:
mapStudent.insert(pair<int,string>(0,"Tongling"));

2、用数组方式插入数据:
    mapStudent[0]="one";
    mapStudent[2]="two";
    mapStudent[5]="three";
其中数组的下标为元素的第一个键值,等号后面的为map的第二个键值。

二、map的遍历

遍历方法也有两种:

1、用迭代器遍历:
map<int,string>::iterator iter;
for (iter = mapStudent.begin();iter != mapStudent.end();iter++)
cout<<iter->first<<" "<<iter->second<<endl;

2、用数组遍历:
for (int nIndex = 0; nIndex < nSize; nIndex++)
cout<<mapStudent[nIndex]<<endl;

大家可以用以下程序,测试一下各种数据类型的赋值方法。
[cpp]  view plain  copy
 print ?
  1. </pre><div style="font-family: 微软雅黑; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: 16px;"><pre name="code" class="cpp">#include <iostream>  
  2. #include <map>  
  3. #include <cstring>  
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     map<int,string> mapStudent;  
  9.     mapStudent[0]="John";  
  10.     mapStudent[2]="Kelly";  
  11.     mapStudent[10000000]="Andy";  
  12.   
  13.     map<int,string>::iterator iter;  
  14.     for(iter = mapStudent.begin();  
  15.         iter !=  mapStudent.end();  
  16.         iter++)  
  17.         cout<<iter->first<<" " <<iter->second<<endl;  
  18.         cout<<endl;  
  19.   
  20.     map<string,string> ID_Student;  
  21.     ID_Student["USC_201300315"] = "Smith";  
  22.     ID_Student["USC_201403419"] = "Bruce";  
  23.     ID_Student["USC_201208125"] = "Sam";  
  24.   
  25.     map<string,string>::iterator it;  
  26.     for(it = ID_Student.begin();  
  27.         it !=ID_Student.end();  
  28.         it++)  
  29.         cout<<it->first<<" "<<it->second<<endl;  
  30.   
  31.     return 0;  
  32. }  



三、判断map的容量

map的大小在往map里面插入了数据:怎么知道当前已经插入了多少数据呢?可以用size函数,用法如下:
int nSize = mapStudent.size();


四、数据的查找:

数据的查找(包括判定这个关键字是否在map中出现)在这里我们将体会,map在数据插入时保证有序的好处。要判定一个数据(或关键字)是否在map中出现的方法比较多,这里虽然说的是数据的查找,但在这里将穿插着大量map的基本用法。这里将给出三种数据查找的方法。

第一种:
用count函数来判定关键字是否出现,由于map的特点是一对一的映射关系,就决定了count的函数返回值只有两个,0或者1,所以无法定位数据出现的位置。

第二种,用find函数来定位数据出现的位置。它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器。如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
程序说明:

[cpp]  view plain  copy
 print ?
  1. #include <iostream>  
  2. #include <map>  
  3. #include <cstring>  
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     map<int,string> mapStudent;  
  9.     mapStudent[0]="John";  
  10.     mapStudent[2]="Kelly";  
  11.     mapStudent[10000000]="Andy";  
  12.   
  13.     map<int,string>::iterator iter;  
  14.   
  15.     iter = mapStudent.find(2);  
  16.     if(iter != mapStudent.end())  
  17.     cout<<iter->second<<endl;  
  18.     else  
  19.         cout<<"don't find"<<endl;  
  20.     return 0;  
  21. }  



五:数据的排序
1、自定义键值排序
其实,为了实现快速查找,map内部本身就是按序存储的。在我们插入<key,value>键值对时,就会按照key的大小进行存储。这也是作为key的类型必须能够进行"<"运算比较的原因。
如果我们用string类型作为key,那么我们的存储就是按照学生姓名的字典序排序储存的。
如果我们想自己写一个compare类,让map按照我们想要的顺序来存储,比如按照学生姓名的长短进行存储,那要怎么做呢?
其实很简单,只要我们自己写一个函数对象,实现想要的逻辑,定义map的时候把compare指定为我们自己编写的这个就可以了。
[cpp]  view plain  copy
 print ?
  1. struct CmpByKeyLength{  
  2.     bool operator()(const string &k1,const string &k2)  
  3.     {  
  4.         return k1.length()<k2.length();  
  5.     }  
  6. };  
  7.   
  8. int main()  
  9. {  
  10.     map<string,string,CmpByKeyLength> ID_Student;  
  11.     ID_Student["Smith"] = "USC_201300315";  
  12.     ID_Student["Jackson"] = "USC_201403419";  
  13.     ID_Student["Sam"] = "USC_201208125";  
  14.   
  15.     map<string,string>::iterator it;  
  16.     for(it = ID_Student.begin();  
  17.         it !=ID_Student.end();  
  18.         it++)  
  19.         cout<<it->first<<" "<<it->second<<endl;  
  20.   
  21.     return 0;  
  22. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值