C++ STL 遍历 map 的时候如何删除其中的 element
首先看一段他人的一段文章:from: http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html
我們通過map的erase(iterator it)方法刪除元素的時(shí)候,如果此時(shí)erase處于遍歷map的代碼中,那么調(diào)用erase就需要小心一些。因?yàn)閑rase會(huì)導(dǎo)致輸入?yún)?shù)iterator變的無效,從而影響后續(xù)的it++遍歷map的邏輯。
簡(jiǎn)單做法是,先將要?jiǎng)h除的it保存下來,然后將用于遍歷map的it指向下一個(gè)位置,然后刪除掉保存下來的it。如下面代碼所示:
#include <map> #include <string> #include <iostream>using namespace std;int main() {map<string, string> map1;map<string, string>::iterator mapit;map<string, string>::iterator saveit;map1["1"] = "2";map1["2"] = "3";map1["3"] = "4";map1["4"] = "5";cout << "Map size1: " << map1.size() << endl;mapit = map1.begin();while (mapit != map1.end()) {cout << "Element key: " << mapit->first << ", value: " << mapit->second << endl;if (mapit->first == "2") {saveit = mapit;mapit++;map1.erase(saveit);continue;}mapit++;} cout << "Map size2: " << map1.size() << endl;return 0; }需要注意的是,這里windows的STL(windows C++編譯器帶的STL)和linux上的STL(gcc的STL)實(shí)現(xiàn)不同。
windows的STL中,map的erase方法會(huì)返回一個(gè)iterator,這個(gè)iterator指向的是當(dāng)前被刪除的iterator后面的iterator,所以這樣的話,只需要將用于循環(huán)的iterator賦成erase函數(shù)的返回值就可以了。參考上面代碼,就是這樣:
mapit = map1.erase(mapit);然后continue就可以。
但是Linux下這樣寫代碼是無法通過編譯的。
--------------------------------------------------------------------------------------------------------------------------------------
另外,我將上面代碼中的while()改了下:
while (mapit != map1.end()) {cout << "Element key: " << mapit->first << ", value: " << mapit->second << endl;if (mapit->first == "2") {saveit = mapit;//mapit++;map1.erase(saveit);//continue;}mapit++;}
經(jīng)過修改之后,在vc6中調(diào)試時(shí)發(fā)現(xiàn)程序運(yùn)行到mapit++;時(shí)就遇到了異常,不調(diào)試程序是可以正常運(yùn)行下去的,但結(jié)果卻不正確,而且與linux下的運(yùn)行結(jié)果也不同。
上述修改后的代碼在vc6中運(yùn)行結(jié)果為:
Map size1: 4 Element key: 1, value: 2 Element key: 2, value: 3 Press any key to continue
在linux中運(yùn)行結(jié)果為:
?
注意到區(qū)別了嗎?再仔細(xì)看看!
?===========================================================
下面是一個(gè)更簡(jiǎn)單(看delValue函數(shù))的寫法,完整程序如下:
/*map遍歷并刪除符合條件的元素 */#ifndef WIN32 #include <string.h> // Linux下得用此文件(strcmp要用到) #else #include <string> #endif#include <iostream> #include <map>using namespace std;void display(map<string, string>& m) {for(map<string, string>::iterator it = m.begin(); it != m.end(); it++){cout << "(" << it->first << ", " << it->second << ")" << endl;}cout << endl; }// 刪除m中值為value的元素, 返回被刪除元素的個(gè)數(shù) int delValue(map<string, string>& m, const char* value) {int delCnt = 0; // 統(tǒng)計(jì)被刪除元素個(gè)數(shù)map<string, string>::iterator it = m.begin();while(it != m.end()){if(strcmp(it->second.c_str(), value) == 0){#if 1 // 此寫法在windows和Linux上都OK(運(yùn)行結(jié)果也正確)m.erase(it++);#else // 此寫法在windows上運(yùn)行程序無法正常退出,應(yīng)該是卡在當(dāng)前while出不來了m.erase(it);it++;#endifdelCnt++;}elseit++;}return delCnt; }int main() {map<string, string> map1;map1["1"] = "3";map1["2"] = "3";map1["3"] = "4";map1["4"] = "3";cout << "Before delete, Map size = " << map1.size() << endl;display(map1); #if 1int c = delValue(map1, "3");cout << "delCnt = " << c << endl; #elsemap<string, string>::iterator mapit;map<string, string>::iterator saveit;mapit = map1.begin();while (mapit != map1.end()) {cout << "Element key: " << mapit->first << ", value: " << mapit->second << endl;if (mapit->first == "2") {saveit = mapit;mapit++;map1.erase(saveit);continue;}mapit++;} #endifcout << "After delete, Map size = " << map1.size() << endl;display(map1);return 0; }總結(jié)
以上是生活随笔為你收集整理的C++ STL 遍历 map 的时候如何删除其中的 element的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fluent UDF【4】:C语言
- 下一篇: Jetty 类载入问题处理