STL Vector remove()、erase()的使用与iterator使用陷阱

STL中remove()的使用

STL中remove()只是将待删除元素之后的元素移动到vector的前端,而不是删除。若要真正移除,需要搭配使用erase()。

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
	vector<int> ar;   //vector containing ar

	ar.push_back(10);
	ar.push_back(20);
	ar.push_back(10);
	ar.push_back(15);
	ar.push_back(12);
	ar.push_back(7);
	ar.push_back(9);

	vector<int>::iterator  it;
	cout << "原始序列" << endl;
	for (it = ar.begin(); it != ar.end(); it++)
		cout << *it << "\t";				//\t 的意思是 横向跳到下一制表符位置
	cout <<"\n"<< endl;					//\n 的意思是回车换行

	// remove all elements from ar that match 10
	vector<int>::iterator ret = remove(ar.begin(), ar.end(), 10);

	cout << "remove之后的序列" << endl;
	for (it = ar.begin(); it != ar.end(); it++)
		cout << *it << "\t";
	cout <<"\n"<< endl;

	cout << "Total number of elements removed from ar = "
		<< ar.end() - ret << endl;

	cout << "有效元素序列" << endl;
	for (it = ar.begin(); it != ret; it++)
		cout << *it << "\t";
	cout << endl;
}

在这里插入图片描述

我们可以看出:

对于原vector { 10 20 10 15 12 7 9 },删除10,会将10后面的元素移动到前面

原vector
10 20 10 15 12 7 9
remove之后
20 15 12 7 9 7 9
因此,remove()需要和erase()配合使用
svec.erase(remove(svec.begin(),svec.end(),“be”), svec.end());
这句的意思是,取得"be"的位置(位于结尾),然后删除"be"到原vector结尾的所有元素

vector中erase用法注意事项

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

#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;

	for (itor = array.begin(); itor != array.end();itor++)
	{
		if (6 == *itor)
			itor = array.erase(itor);
	}

	for (itor = array.begin(); itor != array.end();itor++)
		cout << *itor;
	cout << endl;
	return 0;
}

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

vector<int>::iterator itor;
for(itor=array.begin();itor!=array.end();)
{
    if(6==*itor)
        itor=array.erase(itor);
    else
        itor++;
}

iterator的使用陷阱:

iterator的使用陷阱:
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);
}

这样使用是错误的,因为erase结束后,iter变成了野指针,iter++就产生了错误。

参考博文:
https://blog.csdn.net/dgyanyong/article/details/21268469
https://blog.csdn.net/yockie/article/details/7859330

猜你喜欢

转载自blog.csdn.net/happyjacob/article/details/82789973
今日推荐