日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ STL 遍历 map 的时候如何删除其中的 element

發(fā)布時間:2023/12/9 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ STL 遍历 map 的时候如何删除其中的 element 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

首先看一段他人的一段文章:from: http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html

我們通過map的erase(iterator it)方法刪除元素的時候,如果此時erase處于遍歷map的代碼中,那么調(diào)用erase就需要小心一些。因為erase會導(dǎo)致輸入?yún)?shù)iterator變的無效,從而影響后續(xù)的it++遍歷map的邏輯。

簡單做法是,先將要刪除的it保存下來,然后將用于遍歷map的it指向下一個位置,然后刪除掉保存下來的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)實現(xiàn)不同。

windows的STL中,map的erase方法會返回一個iterator,這個iterator指向的是當前被刪除的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)試時發(fā)現(xiàn)程序運行到mapit++;時就遇到了異常,不調(diào)試程序是可以正常運行下去的,但結(jié)果卻不正確,而且與linux下的運行結(jié)果也不同。

上述修改后的代碼在vc6中運行結(jié)果為:

Map size1: 4 Element key: 1, value: 2 Element key: 2, value: 3 Press any key to continue


在linux中運行結(jié)果為:

[zcm@t #19]$./t Map size1: 4 Element key: 1, value: 2 Element key: 2, value: 3 Element key: 1, value: 2 Element key: 3, value: 4 Element key: 4, value: 5 Map size2: 3

?

注意到區(qū)別了嗎?再仔細看看!

?===========================================================

下面是一個更簡單(看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的元素, 返回被刪除元素的個數(shù) int delValue(map<string, string>& m, const char* value) {int delCnt = 0; // 統(tǒng)計被刪除元素個數(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(運行結(jié)果也正確)m.erase(it++);#else // 此寫法在windows上運行程序無法正常退出,應(yī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的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。