C++ STL 遍历 map 的时候如何删除其中的 element
来源:互联网 发布:淘宝假冒品牌仅退款 编辑:程序博客网 时间:2024/05/29 15:29
首先看一段他人的一段文章:from: http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html
我们通过map的erase(iterator it)方法删除元素的时候,如果此时erase处于遍历map的代码中,那么调用erase就需要小心一些。因为erase会导致输入参数iterator变的无效,从而影响后续的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)实现不同。
windows的STL中,map的erase方法会返回一个iterator,这个iterator指向的是当前被删除的iterator后面的iterator,所以这样的话,只需要将用于循环的iterator赋成erase函数的返回值就可以了。参考上面代码,就是这样:
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++; }
经过修改之后,在vc6中调试时发现程序运行到mapit++;时就遇到了异常,不调试程序是可以正常运行下去的,但结果却不正确,而且与linux下的运行结果也不同。
上述修改后的代码在vc6中运行结果为:
Map size1: 4Element key: 1, value: 2Element key: 2, value: 3Press any key to continue
在linux中运行结果为:
[zcm@t #19]$./tMap size1: 4Element key: 1, value: 2Element key: 2, value: 3Element key: 1, value: 2Element key: 3, value: 4Element key: 4, value: 5Map size2: 3
注意到区别了吗?再仔细看看!
===========================================================
下面是一个更简单(看delValue函数)的写法,完整程序如下:
/*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的元素, 返回被删除元素的个数int delValue(map<string, string>& m, const char* value){int delCnt = 0;// 统计被删除元素个数map<string, string>::iterator it = m.begin();while(it != m.end()){if(strcmp(it->second.c_str(), value) == 0){#if 1// 此写法在windows和Linux上都OK(运行结果也正确)m.erase(it++);#else// 此写法在windows上运行程序无法正常退出,应该是卡在当前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;}
- C++ STL 遍历 map 的时候如何删除其中的 element
- C++ STL遍历map的时候如何删除其中的element
- C++ STL 遍历 map 的时候如何删除其中的 element
- C++ STL遍历map的时候如何删除其中的element
- c++ 遍历map的时候删除元素
- 码农小汪-Map遍历的时候删除元素
- List遍历的时候将其中的元素删除掉
- stl map高效遍历删除的方法
- stl map高效遍历删除的方法
- stl map遍历和删除的方法
- stl map高效遍历删除的方法
- stl map遍历删除的方法
- c++ STL map的增加删除遍历操作
- C++ STL Map的创建、删除、插入、更新、遍历
- 遍历的时候删除List
- 遍历的时候删除List
- stl map vector的删除
- STL Vector 的遍历删除
- 关于Singleton
- 为解压版Tomcat 注册服务
- C# .net 面试题汇总
- module_param()
- 什么是Web 2.0
- C++ STL 遍历 map 的时候如何删除其中的 element
- String类型声明空值变量
- android SDK 4.0(api14) 安装
- android 根据非物理路径得到物理路径
- 学习Windows Phone 7 手机开发的一些资源链接
- php常用算法总结
- fatal error C1088
- 建立权限树TreeView
- ubuntu中添加环境变量