C++學習STL之關聯容器 --- pair、map、set

本博文咱們繼續討論標準模板庫STL的關聯容器;ios

主要有:pair、map、set。c++

一:pair函數

pair是一種簡單的關聯類型,不屬於容器範圍。而是表明一個 key-value鍵值對。性能

建立、初始化、操做 示例代碼以下:測試

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 using namespace std;
 5 //將pair放入容器&initpair
 6 int main(int argc, const char *argv[])
 7 {
 8     vector<pair<string, int> > vec;//初始化vector
 9 
10     pair<string, int> p1;//num.1
11     p1.first = "hello";
12     p1.second = 12 ;
13     vec.push_back(p1);
14 
15     pair<string, int> p2("world", 22);//num.2
16     vec.push_back(p2);
17 
18     vec.push_back(make_pair<string, int>("foo", 44));//num.3
19 
20     for(vector<pair<string,int> >::iterator it = vec.begin(); //g++ main.cc -std=c++0x
21         it != vec.end(); 
22         ++it)
23     {
24         cout << "key: " << it->first << "  val:"<< it->second << endl;    
25     }
26 
27     return 0;
28 }

 二:mapspa

1):map則是一個容器,裏面存儲的是 pair對象。但存儲的方式與vector<pair>這種 連續存儲有所不一樣, map採用的是 二叉排序樹存儲pair,通常是紅黑樹指針

2):map使用下標訪問時,若是 key不存在,那麼會在map 中自動添加一個新的pair,value爲默認值。code

性能分析:因爲map採用二叉排序樹(紅黑樹),樹的高度不超過 [logN] +1。因此 插入和查詢時間複雜度 爲  O(lgN);對象

注意:使用insert插入map元素時,若是失敗,則不會更新原來的值。blog

a):初始化(示例代碼以下):

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <map>
 5 #include <algorithm>
 6 using namespace std;
 7 //Red_black Tree
 8 int main(int argc, const char *argv[])
 9 {
10     map<string, int> m;
11     m["beijing"] = 2000;
12     m["hangzhou"] = 880;
13     m["shanghai"] = 1500;
14 // key --> value  採用二叉排序樹對key排序
15 //兩種打印方式
16     for(map<string, int>::const_iterator it = m.begin();
17         it != m.end();
18         it++)
19     {
20         //*it pair
21         cout << it->first <<":" << it->second << endl;
22     }
23     for(const pair<int, string> &p: m) // -std=c++0x(C++11) 注意要用pair 
24         cout << p.first << ":" << p.second << endl;
25     return 0;
26 }

b):下標訪問

每當用下標訪問map元素的時候,若是元素不存在,那麼會在map中新生成一個鍵值對。因此,用下標訪問不存在的鍵值對時,會增長容器的大小。 (應用:單詞計數程序)

1     map<string, int> word_count;
2     string word;
3     while (cin >> word) {
4         word_count[word]++;  
5     for_each(word_count.begin(), word_count.end(), print);

 c):insert操做(map,set有insert操做, 而vector沒有

示例以下;

 1 //本例測試insert的返回值
 2 int main(int argc, const char *argv[])
 3 {
 4     map<string, int> m ;
 5 
 6     m.insert(make_pair("hello",1));
 7     m.insert(make_pair("wordl",2));
 8     m.insert(make_pair("foo",1));
 9 
10     cout << m.size() << endl; //3
11 
12     //insert的返回值類型
13     pair<map<string, int>::iterator, bool> ret ;
14         //插入成功
15     ret = m.insert(make_pair("faasdf",23));
16     cout << "ret:" << ret.second << endl; //1
17         //插入失敗
18     ret = m.insert(make_pair("hello",234)); //false
19     cout << "ret:" << ret.second << endl;
20     
21     //ret.first 表明指向迭代器的指針。
22     cout << "ret:" << ret.first->second << endl; // 1
23 
24     return 0;
25 }

d):count,find 函數測試 key值得存在性。

注意:下標操做 與 count 的區別

使用下標獲取value值的時候,存在這樣一個弊端,若是下表訪問的是不存在的元素,俺麼會自動給map 增長一個 key-value鍵值對,有時候這不是咱們所預期的。

而count和find能夠較好解決這一問題。

count:僅僅能得出該元素是否存在。

find: 可以返回該元素的迭代器 。

示例代碼以下:

 1 //count、 insert、find 測試key存在性
 2 int main(int argc, const char *argv[])
 3 {
 4     map<string, string> m;
 5     m["beijing"] = "good";
 6     m["shanghai"] ="good";
 7     m["shenzhen"]= "good";
 8 
 9     cout << m.count("beijing") << endl;// 1
10     cout << m.count("HK") << endl;// 0
11     
12     map<string, string>::iterator it = m.find("beijing");
13     //m.find("Hk")--->不存在
14     if(it == m.end())
15         cout << "不存在" <<endl;
16     else
17         cout << it->first <<":" << it->second << endl ; //
18     return 0;
19 }

三:set (停用詞功能)

insert、erase、find操做。

實例代碼以下:

 1 //set 三個性質; 肯定性,惟一性,無序性
 2 //和 map 同樣, 採用 紅黑樹 RB_Tree 有序的  查詢時間複雜度 lgN
 3 int main(int argc, const char *argv[])
 4 {
 5     set<int> s ;
 6     int i;
 7     for (i = 0; i < 20; i++)
 8     {
 9         s.insert(i);
10         s.insert(i);
11     }
12     cout << "size:" <<s.size() << endl;// 20 -->惟一性
13 
14     for(int i : s) // -std=c++0x
15         cout << i << " " ;
16     cout << endl ;
17     return 0;
18 }

注意:set(集合) 與map(映射) 的區別

a)   兩者均使用紅黑樹實現;

b)   key須要支持<操做(可以比較,對於整個結構體而言,則沒法比較);

c)   map側重於key-value的快速查找;

d)   set側重於查看元素是否存在。

共同點:map和set中的元素沒法排序。因爲其具備二叉排序性質,故不能排序。

相關文章
相關標籤/搜索