本博文咱們繼續討論標準模板庫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中的元素沒法排序。因爲其具備二叉排序性質,故不能排序。