迭代器删除的坑
今天在字符串定点删除固定元素的时候,出现了大问题,百思不得其解。
题目简单描述是这样的:
给定一个字符串str,targe元素是‘a’,通过erase方法进行删除
代码是这样的:
#include
using namespace std ;
int main()
{
string str = "ahsdjkafbnaasdfjkanasjkdfbhjasddkaldfasa" ;
for(auto it = str.begin() ; it != str.end() ; ++ it)
{
if(*it == 'a')
{
str.erase(it) ;
}
}
cout << str << endl ;
return 0 ;
}
但是出现了大问题,呜呜呜呜……
在leetcode的ide里面,我是发现了根本删不干净,于是我调试了好久,并且上网查找资料,终于找到了问题所在。
#include
using namespace std ;
int main()
{
string str = "ahsdjkafbnaasdfjkanasjkdfbhjasddkaldfasa" ;
auto it = str.begin() ;
while( it != str.end())
{
if(*it == 'a')
{
str.erase(it) ;
}
else
{
it ++ ;
}
}
cout << str << endl ;
return 0 ;
}
对于关联容器
如map,set,unordered_map容器来说,例如map的底层是由红黑树实现的,当删除一个或者多个节点的时候,并不会导致其他节点的波动。
对于非关联式的容器(序列容器)
例如vector,string,list,queue等容器,这些是有连续分配内存的,所以当删除了当前迭代器的指针,会使后来的元素都往前移动一位,所以会使后续的所有元素的指针都失效。
目前有两种可以用的方法:
第一种是采用while循环:
#include
using namespace std ;
int main()
{
string str = "asfhjkasnaaseelfha" ;
auto it = str.begin() ;
while(it != str.end())
{
if(* it == 'a')
{
str.erase(it) ;
}
else
{
it ++ ;
}
}
cout << str << endl ;
return 0 ;
}
第二种采用的是用erase方法得到下一个有效的迭代器指针:
#include
using namespace std ;
int main()
{
string str = "asfhjkasnaaseelfha" ;
for(auto it = str.begin() ; it != str.end() ; )
{
if(*it == 'a')
{
it = it.erase(it) ;
}
else
{
it ++ ;
}
}
cout << str << endl ;
return 0 ;
}