C++中的vector中erase用法实例代码
信手斩龙 人气:0在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为容器对象,返回值都是一个迭代器,该迭代器指向被删除元素后面的元素(这个是重点)
加载全部内容