迭代器删除的大坑


迭代器删除的坑

今天在字符串定点删除固定元素的时候,出现了大问题,百思不得其解。

题目简单描述是这样的:


给定一个字符串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 ; 
}

文章作者: 罗林
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 罗林 !
  目录