STL--map學習筆記
1、簡介
Map是C++的一個關聯容器,它提供了很好的一對一的關系。(其中一個為關鍵字,每個關鍵字key只能在map中出現一次,第二個可稱為關鍵字的值value)map內部自建一顆紅黑樹(一種嚴格意義上的平衡二叉樹),這顆樹具有對數據自動排序的功能,所以在map內部所有的數據是有序的。
2、功能
map自動建立key---value的對應,key和value可以是任意需要的類型
根據key的值快速查找記錄,查找的復雜度基本是Log(N)
快速插入key---value記錄
快速刪除記錄
根基key修改value記錄
遍歷所有記錄
3、操作
使用map需要#include<map>頭文件
- map最基本本的構造函數
map<string,int>mapstring; map<int,string>mapint; map<string,char>mapstring; map<char,string>mapchar; map<char,int>mapchar; map<int,char>mapint;
插入操作
//用數組方式插入數據 #include<map> #include<iostream> using namespacestd; int main() { map<int,string>mp; mp[1]="stu"; mp[2]="den"; mp[3]="t_one is"; mp[4]=" a boy"; map<int,string>::iterator it; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->second; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; }
//用insert插入pair數據 #include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; mp.insert(pair<int,string>(1,"studentA")); mp.insert(pair<int,string>(2,"is ")); mp.insert(pair<int,string>(3," a boy")); map<int,string>::iterator it; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->second; cout<<endl; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; }
//用insert插入插入value_type數據 #include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); mp.insert(map<int,string>::value_type(3,"studentC ")); map<int,string>::iterator it; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->second; cout<<endl; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; }
以上三種用法雖然都可以實現數據插入,但也是有區別,第二種和第三種效果上是一樣的,用insert函數插入數據在數據的插入上涉及到集合的唯一性這個歌概念,當map種有關鍵字時,insert操作插入數據不了,但用數組方式就不同,他可以覆蓋之前的關鍵字對應的值
-
*驗證
#include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; map<int,string>::iterator it; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; cout<<endl; mp.insert(map<int,string>::value_type(1,"studentC ")); //用insert不能覆蓋mapkey為1中value的值 mp.insert(map<int,string>::value_type(2,"studentD ")); //用insert不能覆蓋mapkey為1中value的值 for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; } //數組形式 #include<map> #include<iostream> using namespace std; int main() { map<int,string>mp; map<int,string>::iterator it; mp[1]="studentA"; mp[2]="studentB"; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; cout<<endl; mp[1]="studentC"; mp[2]="studentD"; for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; }
- 3、map
- map
裏面插入了數據,我們怎麽知道當前已經插入了多少數據呢,可以用size函數,用法如下:
- Int mpSize = mp.size();
- 4、數據遍歷
第一種方法:應用前向叠代器:
#include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; map<int,string>::iterator it; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); mp.insert(map<int,string>::value_type(3,"studentC ")); mp.insert(map<int,string>::value_type(4,"studentC ")); for(it=mp.begin();it!=mp.end();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; }
第二種方法:應用反向叠代器:
#include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; map<int,string>::reverse_iterator it; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); mp.insert(map<int,string>::value_type(3,"studentC ")); mp.insert(map<int,string>::value_type(4,"studentC ")); for(it=mp.rbegin();it!=mp.rend();it++) //遍歷 cout<<it->first<<‘.‘<<it->second<<endl; return 0; }
第三種:用數組形式
#include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; map<int,string>::iterator it; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); mp.insert(map<int,string>::value_type(3,"studentC ")); mp.insert(map<int,string>::value_type(4,"studentD ")); int nsize=mp.size(); //此處應註意,應該是 for(int nindex = 1; nindex <= nSize; nindex++) //而不是 for(int nindex = 0; nindex < nSize; nindex++) for(int nindex=1;nindex<=nsize;nindex++) //遍歷 cout<<nindex<<‘.‘<<mp[nindex]<<endl; return 0; }
5、查找並獲取map種的元素
一、用count函數來判定關鍵字是否出現,其缺點是無法定位數據出現位置,由於map的特性,一對一的映射關系,就決定了count函數的返回值只有兩個,要麽是0,要麽是1,出現的情況,當然是返回1了
二、用find函數來定位數據出現位置,它返回的一個叠代器,當數據出現時,它返回數據所在位置的叠代器,如果map中沒有要查找的數據,它返回的叠代器等於end函數返回的叠代器。
查找map中是否包含某個關鍵字條目用find()方法,傳入的參數是要查找的key,在這裏需要提到的是begin()和end()兩個成員,
分別代表map對象中第一個條目和最後一個條目,這兩個數據的類型是iterator.
#include<map> #include<iostream> #include<cstring> using namespace std; int main() { int n; map<int,string>mp; map<int,string>::iterator it; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); mp.insert(map<int,string>::value_type(3,"studentC ")); mp.insert(map<int,string>::value_type(4,"studentD ")); cin>>n;//要查找map的key值 it=mp.find(n); if(it!=mp.end()) cout<<it->second; else cout<<"no find"<<endl; return 0; }
6、從map種刪除元素
移除某個map中的元素
Iterator erase(iterator it);//通過一個條目對象刪除
Iterator erase(iterator first,iterator last)//刪除一個範圍
Iterator erase(iterator Key&key);//通過關鍵字刪除
Clear()相當於 mp.erase(mp.begin(),mp.end());
#include<map> #include<iostream> #include<cstring> using namespace std; int main() { map<int,string>mp; map<int,string>::iterator it; mp.insert(map<int,string>::value_type(1,"studentA ")); mp.insert(map<int,string>::value_type(2,"studentB ")); mp.insert(map<int,string>::value_type(3,"studentC ")); mp.insert(map<int,string>::value_type(4,"studentD ")); //用叠代器刪除1 /* it=mp.find(1); mp.erase(it); for(map<int,string>::iterator it=mp.begin();it!=mp.end();it++) cout<<it->second<<endl; */ // 利用關鍵字刪除 /* int n=mp.erase(1); //如果刪除了會返回1,否則返回0 cout<<n<<endl; for(map<int,string>::iterator it=mp.begin();it!=mp.end();it++) cout<<it->second<<endl; */ //用叠代器,成片的刪除 /* mp.erase(mp.begin(),mp.end()); //成片刪除要註意的是,也是STL的特性,刪除區間是一個前閉後開的集合 for(map<int,string>::iterator it=mp.begin();it!=mp.end();it++) cout<<it->second<<endl;*/ //測試 時將註釋逐個去掉便可 return 0; }
7、 map中的swap用法
map中的swap不是一個容器中的元素交換,而是兩個容器所有元素的交換。
8、排序 map中的sort問題
map中的元素是自動按Key升序排序,所以不能對map用sort函數;
這裏要講的是一點比較高深的用法了,排序問題,STL中默認是采用小於號來排序的,以上代碼在排序上是不存在任何問題的,因為上面的關鍵字是int 型,它本身支持小於號運算,在一些特殊情況,比如關鍵字是一個結構體,涉及到排序就會出現問題,因為它沒有小於號操作,insert等函數在編譯的時候過 不去,下面給出兩個方法解決這個問題。
//第一種:小於號重載 #include<map> #include<iostream> #include<cstring> using namespace std; typedef struct Student { int id; string stu_name; bool operator < (Student const& _A)const { if(id<_A.id)return true; if(id==_A.id) return stu_name.compare(_A.stu_name)<0; return false; } } stu,*Pstu; int main() { int nsize; //用學生信息映射分數 map<stu ,int>mapstudent; map<stu ,int>::iterator it; stu studentinfo; studentinfo.id=1; studentinfo.stu_name="student A"; mapstudent.insert(map<stu,int>::value_type(studentinfo,90)); studentinfo.id=2; studentinfo.stu_name="student B"; mapstudent.insert(map<stu,int>::value_type(studentinfo,80)); for(it=mapstudent.begin();it!=mapstudent.end();it++) cout<<it->first.id<<‘ ‘<<it->first.stu_name<<‘ ‘<<it->second<<endl; return 0; }
//第二種:仿函數的應用, #include<map> #include<iostream> #include<cstring> using namespace std; typedef struct Student { int id; string stu_name; } stu,*Pstu; class sort { public: bool operator() (stu const &_A,stu const &_B)const { if(_A.id < _B.id) return true; if(_A.id == _B.id) return _A.stu_name.compare(_B.stu_name)<0; return false; } }; int main() { int nsize; //用學生信息映射分數 map<stu ,int,sort>mapstudent; map<stu ,int>::iterator it; stu studentinfo; studentinfo.id=1; studentinfo.stu_name="student A"; mapstudent.insert(pair<stu,int>(studentinfo,90)); studentinfo.id=2; studentinfo.stu_name="student B"; mapstudent.insert(pair<stu,int>(studentinfo,80)); for(it=mapstudent.begin();it!=mapstudent.end();it++) cout<<it->first.id<<‘ ‘<<it->first.stu_name<<‘ ‘<<it->second<<endl; return 0; }
map按value排序
原理說明http://blog.csdn.net/acidgl8757/article/details/17416439
#include<map> #include<algorithm> #include<iostream> #include<cstring> #include<vector> using namespace std; typedef pair<string,int>PAIR; struct cmp { operator()(const PAIR& A,const PAIR& B) { return A.second<B.second; } }; int main() { map<string,int>stu_mp; stu_mp["student_A"]=90; stu_mp["student_B"]=78; stu_mp["student_C"]=92; stu_mp["student_D"]=97; stu_mp.insert(make_pair("student E",99)); vector<PAIR>stu_vec(stu_mp.begin(),stu_mp.end()); sort(stu_vec.begin(),stu_vec.end(),cmp()); map<string,int>::iterator it; cout<<"排序前"<<endl; for(it=stu_mp.begin();it!=stu_mp.end();it++) cout<<it->first<<‘ ‘<<it->second<<endl; cout<<"排序後"<<endl; for(int i=0;i!=stu_vec.size();i++) cout<<stu_vec[i].first<<‘ ‘<<stu_vec[i].second<<endl; return 0; }
map的基本操作函數:
C++ maps是一種關聯式容器,包含“關鍵字/值”對
begin() 返回指向map頭部的叠代器
clear() 刪除所有元素
count() 返回指定元素出現的次數
empty() 如果map為空則返回true
end() 返回指向map末尾的叠代器
equal_range() 返回特殊條目的叠代器對
erase() 刪除一個元素
find() 查找一個元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比較元素key的函數
lower_bound() 返回鍵值>=給定元素的第一個位置
max_size() 返回可以容納的最大元素個數
rbegin() 返回一個指向map尾部的逆向叠代器
rend() 返回一個指向map頭部的逆向叠代器
size() 返回map中元素的個數
swap() 交換兩個map
upper_bound() 返回鍵值>給定元素的第一個位置
value_comp() 返回比較元素value的函數
PS:QAQ此篇是學習map時參照別人的博客寫的,大致思路按照原博客一樣,QAQ我忘記原來的地址了,中間的代碼自己重新寫過,文章先寫在word上,在放在博客上的....排版可能很醜,多多諒解,如有問題,歡迎提出,謝謝大家。
STL--map學習筆記