精华内容
下载资源
问答
  • vector中erase用法注意事项 以前就发现了vector中的erase方法有些诡异(^_^),稍不注意,就会出错。今天又一次遇到了,就索性总结一下,尤其是在循环体中用erase时,由于vector.beg

    http://blog.csdn.net/daofengdeba/article/details/7865229


    vector中erase用法注意事项


    以前就发现了vector中的erase方法有些诡异(^_^),稍不注意,就会出错。今天又一次遇到了,就索性总结一下,尤其是在循环体中用erase时,由于vector.begin() 和vector.end()是变化的,因此就引入了错误的可能性。

    erase的函数原型有两种形式:

    iterator erase(iterator position);

    iterator erase(iterator first, iterator last);

     

    vector<int> veci;
    veci.push_back(1);
    veci.push_back(2);
    veci.push_back(3);
    veci.push_back(4);
    veci.push_back(5);
    veci.push_back(3);
    veci.push_back(2);
    veci.push_back(3);

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
    {
          if( *iter == 3)
                 veci.erase(iter);
    }

    乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。

    查看MSDN,对于erase的返回值是这样描述的:An iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the vector if no such element exists,于是改代码:

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
    {
          if( *iter == 3)
                 iter = veci.erase(iter);
    }

    这段代码也是错误的:1)无法删除两个连续的"3"; 2)当3位于vector最后位置的时候,也会出错(在veci.end()上执行 ++ 操作)

    正确的代码应该为:

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
    {
         if( *iter == 3)
              iter = veci.erase(iter);
          else
                iter ++ ;
    }

     

    为了避免对野指针进行操作,另一种解决方法如下:

    vector<int>::iterator itor2;

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
    {
         if( *iter == 3)

         {   

               itor2=iter;
              veci.erase(itor2);
         }

          else
                iter ++ ;
    }

     

    要解决无法删除两个连续的3的另一种方法如下:

    vector<int>  veci;

    veci.erase(remove(veci.begin(),veci.end(),6),veci.end());

    这里用到了remove()函数,

    注:remove是个stl的通用算法std::remove(first,last,val)移除[first, last)范围内等于val的元素在vector里面用就类似于iter = std::remove(vec.begin(), vec.end(), val)但这个函数只是把val移到vec的末尾,并不真正删除真正删除还是要调用一次erase函数

    展开全文
  •   在vector数组我们删除数组经常用的就是erase方法,但是earse的用法一不注意就会出错,今天我就遇到了,所以在这里总结一下,避免大家用错。 1、首先介绍一下erase函数的原型: iteratorerase(iterator ...

      在vector数组中我们删除数组经常用的就是erase方法,但是earse的用法一不注意就会出错,今天我就遇到了,所以在这里总结一下,避免大家用错。

    1、首先介绍一下erase函数的原型:

    iteratorerase(iterator position);
    iteratorerase(iterator first, iterator last);
    

    我们可以看到erase函数有两种函数原型,一种是给定要删除的位置,另一种是给定删除的区域。

    2、接下来给出一种常见的错误

    for(auto iter=vec.begin();iter!=vec.end(); iter++)
    {
          if(*iter == 3)
                veci.erase(iter);
    }
    

      这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。
      我们通过查阅文档可以看到erase函数的返回值是这么介绍的:一个迭代器,指定在任何删除的元素之后剩余的第一个元素,如果不存在这样的元素,则指定指向向量结尾的指针

    将代码改成这样就可以了:

    for(auto iter=vec.begin();iter!=vec.end(); iter++)
    {
          if(*iter == 3)
                iter = veci.erase(iter);
    }
    

      但是这种代码也是存在缺陷的,首先是我们无法连续删除数字3,其次是迭代器在指向vec.end()的时候,还会进行一次++,这就发生了数组越界,所以我们一概这样修改:

    for(auto iter=vec.begin();iter!=vec.end(); )
    {
         if( *iter == 3)
              iter = veci.erase(iter);//当删除时erase函数自动指向下一个位置,就不需要进行++
          else
                iter ++ ;    //当没有进行删除的时候,迭代器++
    }
    
    另一种解决无法删除连续的数字的方法

    我们先介绍一下remove函数:
    remove是个stl的通用算法std::remove(first,last,val)移除[first, last)范围内等于val的元素在vector里面用就类似于 iter=std::remove(vec.begin(), vec.end(), val)但这个函数只是把val移到vec的末尾,并不真正删除,真正删除还是要调用一次erase函数

    veci.erase(remove(vec.begin(),vec.end(),3),vec.end());
    

    3、删除重复元素,并且顺序不发生变化

      如果不要求顺序的话,我们可以直接调用unique函数进行操作,这里介绍一下unique函数:从头到尾,判断当前元素是否等于上一个元素,将不重复的元素移到前面来(赋值操作),而不是将重复的元素移动到后面去。
    函数的参数是:
    first:去重的起点的迭代器位置。
    last:去重的终点的迭代器位置,不包括
    pred:自定义判断重复方式。
    返回值:去重以后vector中没有重复元素的下一个位置的迭代器。

    vec.erase(unique(vec.begin(),vec.end()),vec.end())  //将重复的区域删除
    
    但是如果要求数字顺序不能发生变化呢?

    这里有两种做法:
    第一种:我们直接对vector数组本身进行操作
    这里我们介绍一下find()函数:函数有3个参数,前两个规定了找的区域,第三个是要找的数字。如果找到,返回其迭代器,找不到返回-1

    void fun(vector<int>& vec)
    {
       for(auto iter=vec.begin(); iter!=vec.end();)
       {
          auto iter1=find(vec.begin(),iter,*iter);
          if(iter!=iter1)  //判断是否重复,如果两者相等说明没有重复
          {
             iter = vec.erase(iter);
          }
          else
             iter++;
       }
    }
    

    第二种:创建一个vector来存放没有重复的元素

    vector<int> fun(vector<int>& vec)
    {
       vector<int> temp;
       for(auto iter=vec.begin(); iter!=vec.end(); iter++;)
       {
          auto iter1=find(vec.begin(),iter,*iter);
          if(iter==iter1) 
          {
             temp.push_back(*iter);
          }        
       }
    }
    

    总结:
      erase()函数的用法: erase()函数用于在顺序型容器中删除容器的一个元素,有两种函数原型,c.erase (p ),c.erase(b,e);第一个删除迭代器p所指向的元素,第二个删除迭代器b,e所标记的范围内的元素,c为容器对象,返回值都是一个迭代器,该迭代器指向被删除元素后面的元素(这个是重点)

    展开全文
  • 以前就发现了vector中erase方法有些诡异(^_^),稍不注意,就会出错。今天又一次遇到了,就索性总结一下,尤其是在循环体中用erase时,由于vector.begin() 和vector.end()是变化的,因此就引入了错误的可能性。 ...

    以前就发现了vector中的erase方法有些诡异(^_^),稍不注意,就会出错。今天又一次遇到了,就索性总结一下,尤其是在循环体中用erase时,由于vector.begin() 和vector.end()是变化的,因此就引入了错误的可能性。

    erase的函数原型有两种形式:

    iterator erase(iterator position);

    iterator erase(iterator first, iterator last);

     

    vector<int> veci;
    veci.push_back(1);
    veci.push_back(2);
    veci.push_back(3);
    veci.push_back(4);
    veci.push_back(5);
    veci.push_back(3);
    veci.push_back(2);
    veci.push_back(3);

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
    {
          if( *iter == 3)
                 veci.erase(iter);
    }

    乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。

    查看MSDN,对于erase的返回值是这样描述的:An iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the vector if no such element exists,于是改代码:

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
    {
          if( *iter == 3)
                 iter = veci.erase(iter);
    }

    这段代码也是错误的:1)无法删除两个连续的"3"; 2)当3位于vector最后位置的时候,也会出错(在veci.end()上执行 ++ 操作)

    正确的代码应该为:

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
    {
         if( *iter == 3)
              iter = veci.erase(iter);
          else
                iter ++ ;
    }

     

    为了避免对野指针进行操作,另一种解决方法如下:

    vector<int>::iterator itor2;

    for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
    {
         if( *iter == 3)

         {   

               itor2=iter;
              veci.erase(itor2);
         }

          else
                iter ++ ;
    }

     

    要解决无法删除两个连续的3的另一种方法如下:

    vector<int>  veci;

    veci.erase(remove(veci.begin(),veci.end(),6),veci.end());

    这里用到了remove()函数,

    注:remove是个stl的通用算法std::remove(first,last,val)移除[first, last)范围内等于val的元素在vector里面用就类似于iter = std::remove(vec.begin(), vec.end(), val)但这个函数只是把val移到vec的末尾,并不真正删除真正删除还是要调用一次erase函数

    展开全文
  • vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase( iterator _Where); iterator erase( iterator _First, iterator _Last); ...


    vector::erase():从指定容器删除指定位置的元素或某段范围内的元素
    vector::erase()方法有两种重载形式
    如下:
    iterator erase(   iterator _Where);
    iterator erase(   iterator _First,   iterator _Last);
    如果是删除指定位置的元素时:
    返回值是一个迭代器,指向删除元素下一个元素;
    如果是删除某范围内的元素时:返回值也表示一个迭代器,指向最后一个删除元素的下一个元素;


    看下面的程序,目的是删除数组里面的所有值为6的元素:


    1. #include<iostream>  
    2. #include<vector>  
    3. using namespace std;  
    4. int main()  
    5. {  
    6.     vector<int> array;  
    7.     array.push_back(1);  
    8.     array.push_back(6);  
    9.     array.push_back(3);  
    10.     array.push_back(6);  
    11.     array.push_back(6);  
    12.     array.push_back(2);  
    13.   
    14.     vector<int>::iterator itor;  
    15.     vector<int>::iterator itor2;  
    16.     for(itor=array.begin();itor!=array.end();)  
    17.     {  
    18.         if(6==*itor)  
    19.         {  
    20.            itor2=itor;  
    21.            itor=array.erase(itor2);  
    22.   
    23.         }  
    24.         itor++;  
    25.     }  
    26.     itor=array.begin();  
    27.     for(itor=array.begin();itor!=array.end();)  
    28.     {  
    29.         cout<<(*itor++);  
    30.     }  
    31.     getchar();  
    32.     return 0;  
    33. }  
    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
        vector<int> array;
        array.push_back(1);
        array.push_back(6);
        array.push_back(3);
        array.push_back(6);
        array.push_back(6);
        array.push_back(2);
    
        vector<int>::iterator itor;
        vector<int>::iterator itor2;
        for(itor=array.begin();itor!=array.end();)
        {
            if(6==*itor)
            {
               itor2=itor;
               itor=array.erase(itor2);
    
            }
            itor++;
        }
        itor=array.begin();
        for(itor=array.begin();itor!=array.end();)
        {
            cout<<(*itor++);
        }
        getchar();
        return 0;
    }


    运行结果输出1362,可见其中一个6并未删除,这是迭代器的问题。
    原因在于erase以后,itor已经指向下一个元素了,不应该在itor++,否则会跳过下一个元素,即连续两个6时跳过了第二个6.
    另外,在itor2=itor时,两个itor是一样的,这样做并无意义。可修改如下:


    1. vector<int>::iterator itor;  
    2. // vector<int>::iterator itor2;  
    3. for(itor=array.begin();itor!=array.end();)  
    4. {  
    5.     if(6==*itor)  
    6.     {  
    7.         // itor2=itor;  
    8.         itor=array.erase(itor);  
    9.     }  
    10.     else  
    11.     {  
    12.         itor++;  
    13.     }  
    14. }  
    vector<int>::iterator itor;
    // vector<int>::iterator itor2;
    for(itor=array.begin();itor!=array.end();)
    {
        if(6==*itor)
        {
            // itor2=itor;
            itor=array.erase(itor);
        }
        else
        {
            itor++;
        }
    }
    


    或者:

    1. vector<int>::iterator itor;  
    2. for(itor=array.begin();itor!=array.end();itor++)  
    3. {  
    4.     if(6==*itor)  
    5.     {  
    6.         itor=array.erase(itor);  
    7.         itor--;  
    8.     }  
    9. }  
    vector<int>::iterator itor;
    for(itor=array.begin();itor!=array.end();itor++)
    {
        if(6==*itor)
        {
            itor=array.erase(itor);
            itor--;
        }
    }

    也可以使用remove方法:
    array.earse( remove(array.begin(), array.end(),6),  array.end() );
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 158
精华内容 63
关键字:

vector中erase用法