STL中remove()和erase()的用法

remove()

示例:

initializer_list<int> list_t = { 1, 2, 1, 3, 4, 1, 5, 6, 7, 8 };
vector<int> vec(list_t);
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); ++it){
	cout << *it << " ";
}
cout << endl;
remove(vec.begin(), vec.end(), 1);
for (it = vec.begin(); it != vec.end(); ++it){
	cout << *it << " ";
}
cout << endl; 

输出结果为:
1 2 1 3 4 1 5 6 7 8
2 3 4 5 6 7 8 6 7 8

调用remove()函数后,容器中的元素个数并没有减少,会发现多出3个元素6,7,8。因为remove()并不是真正的删除元素,而是用后面的元素代替删除元素。也就是说,当删除第一个1时,用2来代替1,删除第二个1时,用3来代替,以此类推。所以多出来的那3个元素没有被删除。

erase()

示例:

initializer_list<int> list_t = { 1, 2, 1, 3, 4, 1, 5, 6, 7, 8 };
vector<int> vec(list_t);
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); ++it){
	cout << *it << "\t";
}
cout << endl;
vec.erase(remove(vec.begin(), vec.end(), 1), vec.end());
for (it = vec.begin(); it != vec.end(); ++it){
	cout << *it << "\t";
}
cout << endl; 

输出结果为:
1 2 1 3 4 1 5 6 7 8
2 3 4 5 6 7 8

接下来在谈谈C++中vector的删除

在vector中有三种涉及删除的方法,第一种是vector::clear(),第二种是vector::erase(),第三种是vector::pop_back()。clear用来清空整个vector,同时将size变成0,无返回值;erase通过传入迭代器进行删除,既可以删除单个元素,也可以删除某一范围的元素,删除之后它将返回下一个位置的迭代器;pop_back用来删除末尾元素,同时将size减1,无返回值。

一般来讲erase用得比较多,不注意也容易踩坑,例如:

vector<int> vec{1, 4, 3, 2, 5, 2};
	
for(auto it = vec.begin(); it != vec.end(); it++){
	if(*it < 3){
		cout << "num is " << *it << endl;
		it = vec.erase(it);
		if(it == vec.end()) break;
	}
}

这个代码如果不在for循环里加上最后的判断会导致错误,原因在于,当it指向最后一个2时,满足删除条件,删除后it变成了end,然后又做了++操作,导致越界。

类似的坑还有许多,这里就不一一列举了,总之,它们的共同点在于对vector进行删除时都不够优雅,需要进行一些额外的处理避免误操作。

事实上,我们完全可以使用提供的remove和remove_if方法,配合erase进行删除。这两个方法并不是真的删除元素,而是以覆盖的方式将满足删除条件的元素移到容器最后(它们具体的实现方式很有意思,但是这里从略,总之有两点:1)它们并没有真的删除元素;2)它们使用了“覆盖”的方式,将要删除的元素移到最后,因此这些元素可能因为被覆盖过而发生改变,但这已经不重要了),然后返回指向第一个要删除位置的迭代器。这样一来,删除就优雅多了,例如:

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

如果再用上lambda,看起来会更酷:

vec.erase(remove_if(vec.begin(), vec.end(), [](int x){return x == 3;}), vec.end());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值