詳解map、multimap、unordered_map、unordered_multimap
詳解map、multimap、unordered_map、unordered_multimap
相信有不少同學和我一樣剛接觸C++ STL,被其深深吸引。但是想弄懂每個模板類不是一個容易事。大家應該對vector、list、stack、queue等類比較瞭解了,所以今天詳細介紹下幾個很常用很強大但有點不太好懂的類map、multimap、unordered_map、unordered_multimap。乍一看都差不多都是什麼map,但這肯定有所不同。下面就在一個一個講解的同時,讓大家瞭解這四個類的使用,以及不同之處。
map
1) 從一個簡單的例子開始
2) #include<map> 3) #include<iostream> 4) using namespace std; 5) 6) int main() 7) { 8) map<char,int> msi; 9) //map::operator[] 10) msi['x'] = 3; 11) msi['z'] = 3; 12) msi['g'] = 2; 13) msi['y'] = 1; 14) //map::at() 15) auto beg = msi.begin(); 16) for(; beg !=msi.end();beg++){ 17) cout<<msi.at(beg->first)<<" "; 18) } 19) cout<<endl; 20) return 1; 21) }
結果: 2 3 1 3 |
程式碼分析:
l map::operator[]
mapped_type& operator[] (const key_type& k);
mapped_type& operator[] (key_type&& k);
該函式通過呼叫mak_pair函式將k,v作為一個kv對,在通過insert函式按照k將v插入map中。
l map::at
mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;
該函式通過k來找到v值。
l 從結果看出,列印是按照k值遞增來列印v值的。
2) 從例子1)繼續
我們對例子1中的程式碼進行下修改。
1) #include<map> 2) #include<iostream> 3) using namespace std; 4) 5) int main() 6) { 7) map<char,int> msi; 8) //map::operator[] 9) msi['x'] = 3; 10) msi['x'] = 4; //這裡修改了 11) msi['g'] = 2; 12) msi['y'] = 1; 13) //map::at() 14) auto beg = msi.begin(); 15) for(; beg !=msi.end();beg++){ 16) cout<<msi.at(beg->first)<<" "; 17) } 18) cout<<endl; 19) return 1; 20) } 結果: 2 4 1 |
程式碼分析:
l 這裡出現了重複key值x,那麼是不是x/3對就被覆蓋了呢????因此只列印出2 41!!!!!
3) 從例子2)繼續
1) int main() 2) { 3) map<char,int> msi; 4) //map::operator[] 5) msi['x'] = 3; 6) msi['x'] = 4; 7) msi['g'] = 2; 8) msi['y'] = 1; 9) //map::at() 10) auto beg = msi.begin(); 11) for(; beg !=msi.end();beg++){ 12) cout<<msi.at(beg->first)<<" "; 13) } 14) cout<<endl; 15) 16) auto get = msi.equal_range('x'); 17) auto skbeg = get.first; 18) auto skend = get.second; 19) for(; skbeg!=skend; skbeg++){ 20) cout<<skbeg->first<<":"<<skbeg->second<<" "; 21) } 22) cout<<endl; 23) 24) return 1; 25) } 結果: 2 4 1 x:4 |
程式碼分析:
l map::equal_range
pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
pair<iterator,iterator> equal_range (const key_type& k);
按照reference中的意思這個函式應該是返回包含k的element的上下界,但是我們並沒有列印出,x:3 x:4。所以呢,嗯我們得出一個結論在map中k和v是一對一的關係,不能出現一個k對應多個v值的情況。
4) OK繼續
1) int main() 2) { 3) map<char,int> msi; 4) //map::operator[] 5) msi['c'] = 3; 6) msi['h'] = 5; 7) msi['b'] = 2; 8) msi['a'] = 1; 9) 10) //insert g 11) msi.insert(pair<char,int>('g',4)); 12) //copy map 13) map<char,int> newmap; 14) newmap.insert(msi.begin(), msi.find('g')); 15) //map::at() 16) auto beg = msi.begin(); 17) for(; beg !=msi.end();beg++){ 18) cout<<beg->first<<"->"<<msi.at(beg->first)<<" "; 19) } 20) cout<<endl; 21) 22) auto newbeg = newmap.begin(); 23) for(; newbeg !=newmap.end();newbeg++) 24) cout<<newbeg->first<<"->"<<newmap.at(newbeg->first)<<" "; 25) cout<<endl; 26) /*auto get = msi.equal_range('x'); 27) auto skbeg = get.first; 28) auto skend = get.second; 29) for(; skbeg!=skend; skbeg++){ 30) cout<<skbeg->first<<":"<<skbeg->second<<" "; 31) }*/ 32) 33) cout<<endl; 34) 35) return 1; 36) } 結果: a->1 b->2 c->3 g->4 h->5 a->1 b->2 c->3 |
程式碼分析:
l map::insert
template <class P> pair<iterator,bool> insert (P&& val);
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
這裡分別使用了這兩種insert函式,其中第一個我們將一個pair物件作為一個element存入map;第二個我們將msi中從開始到g以前的element存入了newmap中。
4) TBC
還有些沒有介紹到的成員函式,我想就在另外幾個類中介紹吧,其實都很簡單…
multimap
1) 直奔主題
1) #include<map> 2) #include<iostream> 3) #include<string> 4) using namespace std; 5) 6) bool cmp(const string &a, const string &b) 7) { 8) return a.compare(b)>0?true:false; 9) } 10) 11) int main() 12) { 13) bool (*cmp_pt) (const string&, const string&) = cmp; 14) multimap<string, int, bool(*) (const string&, const string&)> mci(cmp_pt); //降序 15) mci.insert(pair<string,int>("bb",2)); 16) mci.insert(pair<string,int>("aa",1)); 17) mci.insert(pair<string,int>("cc",3)); 18) mci.insert(pair<string,int>("gg",6)); 19) mci.insert(pair<string,int>("cc",5));//重複 20) 21) auto beg = mci.begin(); 22) for(;beg!=mci.end();beg++){ 23) cout<<beg->first<<"->"<<beg->second<<" "; 24) } 25) cout<<endl; 26) auto skget = mci.equal_range("cc"); 27) auto skbeg = skget.first; 28) auto skend = skget.second; 29) for(;skbeg!=skend;skbeg++ ) 30) cout<<skbeg->first<<"->"<<skbeg->second<<" "; 31) cout<<endl; 32) } 結果: gg->6 cc->3 cc->5 bb->2 aa->1 cc->3 cc->5 |
程式碼分析:
l 降序輸出
這裡有兩種方法,一種是函式指標,一種是類。這裡採用的前者。類方法更加簡單,只需要過載operator()即可,如下所示。
struct
|
std::multimap<char,int,classcomp> fourth; |
l 初始化資料
資料不能通過operator[]給予嘍~,沒這個成員函式。
l 重點來了
可以發現儘管加入了重複鍵值cc/5,但是列印的時候我們依然輸出了重複的鍵值對,因此我們可以說multimap和map的一個最大的區別就是,multimap可以實現一對多的儲存方式!!!!!!!!
unordered_multimap
1) 依然直奔主題
1) #include<iostream> 2) #include<unordered_map> 3) using namespace std; 4) 5) int main() 6) { 7) unordered_multimap<char,int> umci,insertum={ {'b',12},{'w',11} }; 8) umci.insert(make_pair('d',5)); 9) umci.insert(pair<char,int>('a',1)); 10) umci.insert(make_pair('b',2)); 11) umci.insert(make_pair('g',8)); 12) umci.insert(insertum.begin(),insertum.end()); 13) 14) auto beg = umci.begin(); 15) for(;beg!=umci.end();beg++) 16) cout<<beg->first<<"->"<<beg->second<<" "; 17) cout<<endl; 18) 19) return 1; 20) } 結果: g->8 b->12 b->2 w->11 a->1 d->5 |
程式碼分析:
l 無序儲存
可以明顯的看出unordered_multimap的無序儲存特點,這是其與multimap最大的區別。
相關文章
- map/ multimap容器
- stl原始碼分析——map/multimap原始碼
- c++ map和unordered_map比較C++
- Cpp學習 -- <unordered_map>
- STL裡的multimap使用詳解
- 用struct做unordered_map的keyStruct
- 陣列,map,unordered_map的簡單效能測試陣列
- map、unordered_map、set 和 unordered_set的小介紹
- unordered_map隨機底數種子隨機
- 例說資料結構&STL(十一)——hash_map/unordered_map資料結構
- c++ unordered_map/set自定義物件的hashC++物件
- 關於c++ STL map 和 unordered_map 的效率的對比測試C++
- JavaScript Source Map 詳解JavaScript
- java Map及Map.Entry詳解Java
- 詳解Map.merge()
- JavaScript中 Map 物件詳解JavaScript物件
- STL中map用法詳解
- 詳解object detection中的mAPObject
- JavaScript --- Map集合結構詳解JavaScript
- JavaScript — Map集合結構詳解JavaScript
- 詳解java的Collection和MapJava
- js迴圈(for/for in/forEach/map/for of)詳解JS
- JAVA集合詳解(Collection和Map介面)Java
- C++中map的使用詳解說明C++
- es6 map、foreach、reduce、 filter 詳解Filter
- 詳解Java 容器(第④篇)——容器原始碼分析 - MapJava原始碼
- Java map 詳解 - 用法、遍歷、排序、常用API等Java排序API
- C++ STL:std::unorderd_map 物理結構詳解C++
- 詳解Java 容器(完結篇)——詳解容器的設計模式、List、Map、併發容器Java設計模式
- 《STL原始碼剖析》-- stl_multimap.h原始碼
- Java集合中List,Set以及Map等集合體系詳解(史上最全)Java
- JavaScript 中 forEach、map、filter 詳細JavaScriptFilter
- Pandas 資料處理三板斧——map、apply、applymap 詳解APP
- JavaScript中的new map()和new set()使用詳細(new map()和new set()的區別)JavaScript
- EventBus原始碼解讀詳細註釋(4)register時重新整理的兩個map原始碼
- 解碼 xsync 的 map 實現
- 第十三篇:multimap容器和multiset容器中的find操作
- PostgreSQL FSM(Free Space Map) 原始碼解讀SQL原始碼