【1】map容器ios
map 是關聯容器。容器中的每個元素都是由一個鍵值和一個數據值組成的。數組
set 是一個集合它以其元素做爲鍵值(同一個鍵值只能出現一次),且默認以升序排列。less
list 是一個順序容器。函數
【2】map容器使用方法以及實例spa
(1)定義、插入數據方法實例指針
1 // map容器定義、插入數據方式代碼 2 #include<map> 3 #include<string> 4 #include<iostream> 5 using namespace std; 6 7 // 打印map容器數據 8 void print(map<int, string>& mapStu, int nValue) 9 { 10 cout << "mapStu" << nValue << "數據信息:" << endl; 11 cout << "size: " << mapStu.size() << endl; 12 map<int, string>::iterator iter = mapStu.begin(); 13 for (; iter != mapStu.end(); ++iter) 14 { 15 cout << "key: " << iter->first << " value: " << iter->second << endl; 16 } 17 cout << endl; 18 } 19 20 void main() 21 { 22 // 第一種定義map的方法 23 map<int, string> mapStu1; 24 // 第二種定義map的方法 25 typedef map<int, string> mapType; 26 mapType mapStu2, mapStu3, mapStu4; 27 28 // 第一種插入數據方法:用insert函數插入value_type數據 29 mapStu1.insert(map<int, string>::value_type(1, "Qin")); 30 mapStu1.insert(map<int, string>::value_type(2, "Sun")); 31 mapStu1.insert(map<int, string>::value_type(3, "Wang")); 32 mapStu1.insert(map<int, string>::value_type(2, "Zhao")); 33 print(mapStu1, 1); 34 // 第二種插入數據方法:用insert函數插入pair數據 35 mapStu2.insert(pair<int, string>(1, "Qin")); 36 mapStu2.insert(pair<int, string>(2, "Sun")); 37 mapStu2.insert(pair<int, string>(3, "Wang")); 38 mapStu2.insert(pair<int, string>(2, "Zhao")); 39 print(mapStu2, 2); 40 // 第三種插入數據方法:用insert函數插入make_pair數據 41 mapStu3.insert(make_pair<int, string>(1, "Qin")); 42 mapStu3.insert(make_pair<int, string>(2, "Sun")); 43 mapStu3.insert(make_pair<int, string>(3, "Wang")); 44 mapStu3.insert(make_pair<int, string>(2, "Zhao")); 45 print(mapStu3, 3); 46 // 第四種插入數據方法:數組插入法 47 mapStu4[1] = "Qin"; 48 mapStu4[2] = "Sun"; 49 mapStu4[3] = "Wang"; 50 mapStu4[2] = "Zhao"; 51 print(mapStu4, 4); 52 53 pair<map<int, string>::iterator, bool> iter_pair; 54 iter_pair = mapStu1.insert(map<int, string>::value_type(3, "Li")); 55 cout << "插入成功與否:" << iter_pair.second << endl; 56 57 system("pause"); 58 } 59 60 // run out 61 /* 62 mapStu1數據信息: 63 size: 3 64 key: 1 value: Qin 65 key: 2 value: Sun 66 key: 3 value: Wang 67 68 mapStu2數據信息: 69 size: 3 70 key: 1 value: Qin 71 key: 2 value: Sun 72 key: 3 value: Wang 73 74 mapStu3數據信息: 75 size: 3 76 key: 1 value: Qin 77 key: 2 value: Sun 78 key: 3 value: Wang 79 80 mapStu4數據信息: 81 size: 3 82 key: 1 value: Qin 83 key: 2 value: Zhao 84 key: 3 value: Wang 85 86 插入成功與否:0 87 請按任意鍵繼續. . . 88 */
分析總結:code
以上四種用法,雖然均可以實現數據的插入,可是它們是有區別的。blog
固然,第1、2、三種在效果上是徹底同樣的,用insert函數插入數據,在數據的插入過程當中涉及到集合的惟一性這個概念:排序
即當map中有這個關鍵字時,insert操做再插入數據是不會成功的。編譯器
可是,用數組(第四種)方式就不一樣了,它能夠覆蓋之前該關鍵字對應的值,用程序說明以下:
mapStu1.insert(map<int, string>::value_type(2, "Sun"));
mapStu1.insert(map<int, string>::value_type(2, "Zhao"));
上面這兩條語句執行後,mapStu1中2這個關鍵字對應的值是「Sun」,第二條語句並無生效。
那麼,這就涉及到咱們怎麼知道insert語句是否插入成功的問題?能夠用pair來得到是否插入成功,程序以下:
pair<map<int, string>::iterator, bool> iter_pair;
iter_pair = mapStu1.insert(map<int, string>::value_type(3, "Li"));
咱們經過pair的第二個變量來判斷是否插入成功,它的第一個變量返回的是一個map的迭代器,
若是插入成功的話迭代器的變量iter_pair.second應該是true,不然爲false。
(2)遍歷map容器的三種方式
程序代碼以下:
1 #include <map> 2 #include <iostream> 3 #include <string> 4 using namespace std; 5 6 // 第一種方式 7 void print1(map<int, string>& mapStu) 8 { 9 cout << "第一種遍歷方式:" << endl; 10 cout << "size: " << mapStu.size() << endl; 11 // 迭代map容器中的數據 12 map<int, string>::iterator iter = mapStu.begin(); 13 for (; iter != mapStu.end(); ++iter) 14 { 15 cout << "key: " << iter->first << " value: " << iter->second << endl; 16 } 17 cout << endl; 18 } 19 20 // 第二種方式 21 void print2(map<int, string>& mapStu) 22 { 23 cout << "第二種遍歷方式:" << endl; 24 cout << "size: " << mapStu.size() << endl; 25 // 迭代map容器中的數據 26 map<int, string>::reverse_iterator iter = mapStu.rbegin(); 27 for (; iter != mapStu.rend(); ++iter) 28 { 29 cout << "key: " << iter->first << " value: " << iter->second << endl; 30 } 31 32 cout << endl; 33 } 34 35 // 第三種方式 36 void print3(map<int, string>& mapStu) 37 { 38 cout << "第三種遍歷方式:" << endl; 39 int nSize = mapStu.size(); 40 cout << "size: " << mapStu.size() << endl; 41 // 迭代map容器中的數據 42 for(int nIndex = 1; nIndex < nSize + 1; ++nIndex) 43 { 44 cout << "<" << nIndex << " :: " << mapStu[nIndex] << ">" << endl; 45 } 46 } 47 48 void main() 49 { 50 typedef map<int, string> mapType; 51 mapType mapStu; 52 53 // 用insert函數插入value_type數據 54 mapStu.insert(map<int, string>::value_type(1, "Qin")); 55 mapStu.insert(map<int, string>::value_type(2, "Sun")); 56 mapStu.insert(map<int, string>::value_type(3, "Wang")); 57 mapStu.insert(map<int, string>::value_type(4, "Zhao")); 58 print1(mapStu); // 第一種方式 59 print2(mapStu); // 第二種方式 60 print3(mapStu); // 第三種方式 61 62 system("pause"); 63 } 64 // run out: 65 /* 66 第一種遍歷方式: 67 size: 4 68 key: 1 value: Qin 69 key: 2 value: Sun 70 key: 3 value: Wang 71 key: 4 value: Zhao 72 73 第二種遍歷方式: 74 size: 4 75 key: 4 value: Zhao 76 key: 3 value: Wang 77 key: 2 value: Sun 78 key: 1 value: Qin 79 80 第三種遍歷方式: 81 size: 4 82 <1 :: Qin> 83 <2 :: Sun> 84 <3 :: Wang> 85 <4 :: Zhao> 86 請按任意鍵繼續. . . 87 */
(3)查找數據的三種方式
應用實例代碼以下:
1 // 三種查找數據的方式 2 #include <map> 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 7 // 第一種方式 8 void print1(map<int, string>& mapStu) 9 { 10 cout << "遍歷容器數據:" << endl; 11 cout << "size: " << mapStu.size() << endl; 12 // 迭代map容器中的數據 13 map<int, string>::iterator iter = mapStu.begin(); 14 for (; iter != mapStu.end(); ++iter) 15 { 16 cout << "key: " << iter->first << " value: " << iter->second << endl; 17 } 18 } 19 20 void main() 21 { 22 typedef map<int, string> mapType; 23 mapType mapStu; 24 25 // 用insert函數插入value_type數據 26 mapStu.insert(map<int, string>::value_type(1, "Qin")); 27 mapStu.insert(map<int, string>::value_type(2, "Sun")); 28 mapStu.insert(map<int, string>::value_type(3, "Wang")); 29 mapStu.insert(map<int, string>::value_type(4, "Zhao")); 30 // 第一種查找數據方式 31 // count函數求的是關鍵字key的個數?key是不能重複的,因此返回只有0和1兩種結果。 32 cout << "查找關鍵字3的結果 : " << mapStu.count(1) << endl; 33 cout << "查找關鍵字5的結果: " << mapStu.count(5) << endl; 34 // 第二種查找數據方式 35 map<int, string>::iterator iter; 36 iter = mapStu.find(1); 37 if (iter != mapStu.end()) 38 { 39 cout << "Find, the value is " << iter->second << endl; 40 } 41 else 42 { 43 cout << "Do not Find !" << endl; 44 } 45 // 第三種查找數據方式 46 print1(mapStu); 47 iter = mapStu.lower_bound(2); 48 { 49 cout << "lower_bound(2) :: (不小於2) " << iter->second << endl; 50 } 51 52 iter = mapStu.lower_bound(3); 53 { 54 cout << "lower_bound(3) :: (不小於3) " << iter->second << endl; 55 } 56 57 iter = mapStu.upper_bound(2); 58 { 59 cout << "upper_bound(2) :: (大於2) " << iter->second << endl; 60 } 61 62 iter = mapStu.upper_bound(3); 63 { 64 cout << "upper_bound(3) :: (大於3) " << iter->second << endl; 65 } 66 67 pair<map<int, string>::iterator, map<int, string>::iterator> mapPair; 68 mapPair = mapStu.equal_range(2); 69 if (mapPair.first == mapPair.second) 70 { 71 cout << "equal_range(2) :: Do not Find!" << endl; 72 } 73 else 74 { 75 cout << "equal_range(2) :: Find!" << endl; 76 } 77 78 mapPair = mapStu.equal_range(5); 79 if (mapPair.first == mapPair.second) 80 { 81 cout << "equal_range(5) :: Do not Find!" << endl; 82 } 83 else 84 { 85 cout << "equal_range(5) :: Find!" << endl; 86 } 87 88 system("pause"); 89 } 90 // run out: 91 /* 92 查找關鍵字3的結果 : 1 93 查找關鍵字5的結果: 0 94 Find, the value is Qin 95 遍歷容器數據: 96 size: 4 97 key: 1 value: Qin 98 key: 2 value: Sun 99 key: 3 value: Wang 100 key: 4 value: Zhao 101 lower_bound(2) :: (不小於2) Sun 102 lower_bound(3) :: (不小於3) Wang 103 upper_bound(2) :: (大於2) Wang 104 upper_bound(3) :: (大於3) Zhao 105 equal_range(2) :: Find! 106 equal_range(5) :: Do not Find! 107 請按任意鍵繼續. . . 108 */
注意:
lower_bound(x)不是下界,而是大於等於x的最小值。
upper_bound(x) 大於x的最小值。
(4)查詢、修改、刪除、大小、比較、清空、判空等等方法。
應用實例代碼以下:
1 #include <map> 2 #include <string> 3 #include <iostream> 4 using namespace std; 5 6 // 打印map容器數據 7 void print(map<int, string>& mapStu) 8 { 9 cout << "size: " << mapStu.size() << endl; 10 // 迭代map容器中的數據 11 map<int, string>::iterator iter = mapStu.begin(); 12 for (; iter != mapStu.end(); ++iter) 13 { 14 cout << "key: " << iter->first << " value: " << iter->second << endl; 15 } 16 cout << endl; 17 } 18 19 void main() 20 { 21 typedef map<int, string> mapType; 22 mapType mapStu1; 23 24 // 用insert函數插入value_type數據 25 mapStu1.insert(map<int, string>::value_type(1, "Qin")); 26 mapStu1.insert(map<int, string>::value_type(2, "Sun")); 27 mapStu1.insert(map<int, string>::value_type(3, "Wang")); 28 mapStu1.insert(map<int, string>::value_type(2, "Zhao")); 29 print(mapStu1); 30 // 查找數據的兩種方式: 31 // 方式1: 32 string str2 = mapStu1[2]; 33 cout << str2 << endl; 34 // 方式2: 35 mapType::iterator my_Iter; 36 my_Iter = mapStu1.find(3); 37 string str3 = my_Iter->second; 38 cout << str3 << endl << endl; 39 // 修改數據的兩種方式: 40 // 方式1: 41 mapStu1[2] = "Ma"; 42 // 方式2: 43 my_Iter->second = "Yuan"; 44 print(mapStu1); 45 // size 函數 和 empty函數 46 cout << "size() :: " << mapStu1.size() << endl; 47 cout << "empty() :: " << mapStu1.empty() << endl; 48 mapStu1.clear(); 49 cout << "size() :: " << mapStu1.size() << endl; 50 cout << "empty() :: " << mapStu1.empty() << endl; 51 // 比較 ==、>=、<=、!= 52 mapType mapStu2; 53 cout << "mapStu1 == mapStu2 :: " << (mapStu1 == mapStu2) << endl; 54 cout << "mapStu1 >= mapStu2 :: " << (mapStu1 >= mapStu2) << endl; 55 cout << "mapStu1 <= mapStu2 :: " << (mapStu1 <= mapStu2) << endl; 56 cout << "mapStu1 != mapStu2 :: " << (mapStu1 != mapStu2) << endl << endl; 57 58 mapStu1.insert(map<int, string>::value_type(1, "Qin")); 59 mapStu1.insert(map<int, string>::value_type(2, "Sun")); 60 mapStu1.insert(map<int, string>::value_type(3, "Wang")); 61 mapStu1.insert(map<int, string>::value_type(4, "Qiang")); 62 mapStu1.insert(map<int, string>::value_type(5, "Huang")); 63 mapStu1.insert(map<int, string>::value_type(6, "Li")); 64 mapStu1.insert(map<int, string>::value_type(7, "Hou")); 65 mapStu1.insert(map<int, string>::value_type(8, "Lin")); 66 mapStu1.insert(map<int, string>::value_type(9, "Li")); 67 68 // 刪除操做 69 cout << "刪除前打印數據信息:" << endl; 70 print(mapStu1); 71 mapType::iterator iter; 72 // 第一種刪除(代碼1) 73 for (iter = mapStu1.begin(); iter != mapStu1.end();) 74 { 75 if (5 == iter->first) 76 { 77 iter = mapStu1.erase(iter); 78 } 79 else 80 { 81 ++iter; 82 } 83 } 84 85 // 第一種刪除(代碼2)(注意代碼層面的差別) 86 for (iter = mapStu1.begin(); iter != mapStu1.end();) 87 { 88 if ("Li" == iter->second) 89 { 90 mapStu1.erase(iter++); 91 } 92 else 93 { 94 ++iter; 95 } 96 } 97 cout << "刪除關鍵字5 以及 值「Li」後: " << endl; 98 print(mapStu1); 99 100 // 第一種刪除(代碼3)(注意代碼層面的差別) 101 my_Iter = mapStu1.find(2); 102 mapStu1.erase(my_Iter); 103 cout << "刪除關鍵字2後: " << endl; 104 print(mapStu1); 105 106 // 第二種刪除(直接刪除關鍵字) 107 int nResult = mapStu1.erase(3); // 若是刪除了會返回1,不然返回0 108 cout << nResult << endl; 109 cout << "刪除關鍵字3後: " << endl; 110 print(mapStu1); 111 112 // 第三種刪除(用迭代器,成片的刪除) 113 mapStu1.erase(++mapStu1.begin(), mapStu1.end()); 114 cout << "剩第一位,其它所有刪除後: " << endl; 115 print(mapStu1); 116 117 system("pause"); 118 } 119 120 // run out: 121 /* 122 size: 3 123 key: 1 value: Qin 124 key: 2 value: Sun 125 key: 3 value: Wang 126 127 Sun 128 Wang 129 130 size: 3 131 key: 1 value: Qin 132 key: 2 value: Ma 133 key: 3 value: Yuan 134 135 size() :: 3 136 empty() :: 0 137 size() :: 0 138 empty() :: 1 139 mapStu1 == mapStu2 :: 1 140 mapStu1 >= mapStu2 :: 1 141 mapStu1 <= mapStu2 :: 1 142 mapStu1 != mapStu2 :: 0 143 144 刪除前打印數據信息: 145 size: 9 146 key: 1 value: Qin 147 key: 2 value: Sun 148 key: 3 value: Wang 149 key: 4 value: Qiang 150 key: 5 value: Huang 151 key: 6 value: Li 152 key: 7 value: Hou 153 key: 8 value: Lin 154 key: 9 value: Li 155 156 刪除關鍵字5 以及 值「Li」後: 157 size: 6 158 key: 1 value: Qin 159 key: 2 value: Sun 160 key: 3 value: Wang 161 key: 4 value: Qiang 162 key: 7 value: Hou 163 key: 8 value: Lin 164 165 刪除關鍵字2後: 166 size: 5 167 key: 1 value: Qin 168 key: 3 value: Wang 169 key: 4 value: Qiang 170 key: 7 value: Hou 171 key: 8 value: Lin 172 173 1 174 刪除關鍵字3後: 175 size: 4 176 key: 1 value: Qin 177 key: 4 value: Qiang 178 key: 7 value: Hou 179 key: 8 value: Lin 180 181 剩第一位,其它所有刪除後: 182 size: 1 183 key: 1 value: Qin 184 185 請按任意鍵繼續. . . 186 */
(5)map 容器排序問題
請看下面一段代碼:
1 #include <map> 2 #include <cstring> 3 using namespace std; 4 5 typedef struct tagStudentInfo 6 { 7 int nID; 8 string strName; 9 } StudentInfo, *PStudentInfo; // 學生信息 10 11 void main() 12 { 13 // 用學生信息映射分數 14 map<StudentInfo, int> mapStudent; 15 StudentInfo studentInfo; 16 studentInfo.nID = 1; 17 studentInfo.strName = "student_one"; 18 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90)); 19 studentInfo.nID = 2; 20 studentInfo.strName = "student_two"; 21 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80)); 22 }
注意:以上程序編譯沒法經過!
由編譯器錯誤提示分析:排序問題!STL中默認是採用小於號來排序的,當關鍵字是一個結構體時,涉及到排序就會出現問題。
由於它沒有小於號操做,insert等函數在編譯的時候過不去,下面給出兩個方法解決這個問題:
一、解決方法1,重載運算符。
1 // 解決方法1 2 3 #include <map> 4 #include <cstring> 5 using namespace std; 6 7 typedef struct tagStudentInfo 8 { 9 int nID; 10 string strName; 11 12 bool operator < (tagStudentInfo const & _A)const 13 { 14 // 這個函數指定排序策略,按nID排序,若是nID相等的話,按strName排序。 15 if (nID < _A.nID) 16 return true; 17 if (nID == _A.nID) 18 return strName.compare(_A.strName) < 0; 19 20 return false; 21 } 22 } StudentInfo, *PStudentInfo; // 學生信息 23 24 void main() 25 { 26 // 用學生信息映射分數 27 map<StudentInfo, int> mapStudent; 28 StudentInfo studentInfo; 29 studentInfo.nID = 1; 30 studentInfo.strName = "student_one"; 31 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90)); 32 studentInfo.nID = 2; 33 studentInfo.strName = "student_two"; 34 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80)); 35 }
二、解決方法2,仿函數。
1 // 解決方法2 2 3 #include <map> 4 #include <cstring> 5 using namespace std; 6 7 typedef struct tagStudentInfo 8 { 9 int nID; 10 string strName; 11 } StudentInfo, *PStudentInfo; // 學生信息 12 13 class sort 14 { 15 public: 16 bool operator()(StudentInfo const & _A, StudentInfo const & _B) const 17 { 18 if (_A.nID < _B.nID) 19 return true; 20 if (_A.nID == _B.nID) 21 return _A.strName.compare(_B.strName) < 0; 22 23 return false; 24 } 25 }; 26 27 void main() 28 { 29 // 用學生信息映射分數 30 map<StudentInfo, int, sort> mapStudent; 31 StudentInfo studentInfo; 32 studentInfo.nID = 1; 33 studentInfo.strName = "student_one"; 34 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90)); 35 studentInfo.nID = 2; 36 studentInfo.strName = "student_two"; 37 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80)); 38 }
(6)待續...
【3】總結說明
(1)因爲STL是一個統一的總體,map的不少用法都和STL中其它的東西結合在一塊兒。
好比,在排序方面,這裏默認用的是小於號,即less<>,若是要從大到小排序呢,這裏涉及到的東西不少,在此沒法一一加以說明。
(2)map容器內部有序,由紅黑樹保證,所以不少函數執行的時間複雜度都是log2N的,用map函數能夠實現的功能,而STL Algorithm也能夠完成該功能。
可是,建議用map自帶函數,效率更高一些。
(3)map在空間上的特性。
因爲map的每一個數據對應紅黑樹上的一個節點,這個節點在不保存你的數據時,是佔用16個字節:
一個父節點指針,左右兩個孩子指針,還有一個枚舉值(標示紅黑的,至關於平衡二叉樹中的平衡因子)。
Good Good Study, Day Day Up.
順序 選擇 循環 總結