网站维护专业,福田做网站联系电话,大连博硕网站建设,asp网站源码免费下载首先看一段他人的一段文章#xff1a;from: http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html
我们通过map的erase(iterator it)方法删除元素的时候#xff0c;如果此时erase处于遍历map的代码中#xff0c;那么调用erase就需要小心一些。因为erase会导致…首先看一段他人的一段文章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()
{
mapstring, string map1;
mapstring, string::iterator mapit;
mapstring, 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的STLwindows C编译器带的STL和linux上的STLgcc的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: 4
Element key: 1, value: 2
Element key: 2, value: 3
Press any key to continue 在linux中运行结果为
[zcmt #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
注意到区别了吗再仔细看看! 下面是一个更简单(看delValue函数)的写法完整程序如下 /*
map遍历并删除符合条件的元素
*/
#ifndef WIN32
#include string.h // Linux下得用此文件(strcmp要用到)
#else
#include string
#endif
#include iostream
#include map
using namespace std;
void display(mapstring, string m)
{
for(mapstring, string::iterator it m.begin(); it ! m.end(); it)
{
cout ( it-first , it-second ) endl;
}
cout endl;
}
// 删除m中值为value的元素, 返回被删除元素的个数
int delValue(mapstring, string m, const char* value)
{
int delCnt 0; // 统计被删除元素个数
mapstring, 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;
#endif
delCnt;
}
else
it;
}
return delCnt;
}
int main()
{
mapstring, 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 1
int c delValue(map1, 3);
cout delCnt c endl;
#else
mapstring, string::iterator mapit;
mapstring, 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;
}
#endif
cout After delete, Map size map1.size() endl;
display(map1);
return 0;
}