菜鸟笔记
提升您的技术认知

vector 中元素的删除

vector 中删除元素的方法是:b.erase(it);  //b是vector, it 是 vector::iterator

但是删除vector 中的元素有些诡异(^_^),稍不注意,就会出错。 

下面先给出基本vector ,如下代码,然后我们来删除为3的元素。

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
 
using namespace std;

int main()
{
	int a[7] = {1,2,3,3,4,5,3};
	//通过数组a的地址初始化,注意地址是从0到5(左闭右开区间)
	vector<int> b(a, a+7);
	vector<int>::iterator  it;

	for(it = b.begin(); it != b.end(); it++)
	{
		cout << *it << "\t" ;
	}
	cout << "\n" << endl ;
}

 

第一个代码如下,这个是错误的:

	for(it=b.begin(); it!=b.end(); it++)
	{
		  if( *it == 3)
				 b.erase(it);
	}

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

查看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( it=b.begin(); it!=b.end(); it++)
	{
	if( *it== 3)
	it= b.erase(it);
	}

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

正确的代码应该为:

	for( it=b.begin(); it!=b.end();)
	{
	if( *it== 3)
		it= b.erase(it);
	else 
		it++;
	}

在后面添加

for(it = b.begin(); it != b.end(); it++)
	{
		cout << *it << "\t" ;
	}
	cout << "\n" << endl ;

核实我们实现了预期。 1 2 4  5

下面用另一个代码方式实现,这也是正确的代码:

	for(int i=0;i<b.size();)
	{
		if(b[i]==3)
			b.erase(b.begin()+i);
		else
			i++;
	}

 这2个代码的关键是去掉it++ 或者 i++, 这个在代码循环里不删除元素时才运行,都在else 里面。