C++标准库---序列式容器的移除算法

remove 移除(但不删除)

移除[fist,last)之中所有与value相等的元素。这一算法并不真正从容器中删除那些元素(换句话说容器大小并未改变),而是将每一个不与value相等(也就是不打算移除)的元素轮番赋给first之后的空间。
返回值ForwardIterator标示出重新整理后的最后元素的下一位置。

如果要删除那些残余数据,可将返回的迭代器交给所在容器的erase() member function。

remove_copy():

移除[first,last)区间内所有与value相等的元素。它并不真正从容器中删除那些元素(换句话说,原容器没有任何改变),而是将结果复制到一个以result标示起始位置的容器身上。
新容器可以和原容器重叠,但如果对新容器实际给值时,超越了旧容器的大小,会产生无法预期的结果。返回值OutputIterator指出被复制的最后元素的下一位置。

注意:array不适合使用remove()和remove_if(),因为array无法缩小尺寸,导致残余数据永远存在。对array而言,较受欢迎的算法是remove_copy()和remove_copy_if()。


STL源码:

template<class ForwardIterator,class T>
ForwardIterator remove(ForwardIterator first,ForwardIterator last, const T& value)
{
    first=find(first,last,value);
	ForwardIterator next=first;

	return first==last?first:remove_copy(++next,last,first,value);
}

remove_copy

template<class InputIterator,class OutputIterator,class T>
OutputIterator remove_copy(InputIterator first,InputIterator last,OutputIterator result,const T& value)
{
    for(;first!=last;++first)
	{
	    *result=*first;
		++result;
	}
	return *result;
}


注意:对于容器vector和deque,使用算法remove,可以移除与value值相等的元素,并返回重新整理后的最后一个元素的下一个位置。
对于list来说,可以使用算法remove来移除与value值相等的元素,并返回重新整理后的最后一个元素的下一个位置,也可以使用自身的成员函数remove,推荐使用效率更高的成员函数。
而对于标准关联式容器,直接使用earse来移除与value相等的元素,是最佳的方案。


代码示例:

//测试remove
#include<iostream>
#include<algorithm>
#include<vector>
#include<deque>
#include<list>
#include<iterator>

using namespace std;

int main()
{
	int data[]={-2,0,-3,1,1,0,-2,1,1,10};

	//测试vector---在移除过程中每一步的结果
	cout<<"coll: "<<endl;

	vector<int> coll(data,data+10);
	vector<int>::iterator pos;

	//输出原序列元素
	copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	//移除1,返回重新整理后的最后一个位置
	pos=remove(coll.begin(),coll.end(),1);

	//输出“删除”后的序列,序列大小不变
	copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	//输出真正移除后剩余的元素
	copy(coll.begin(),pos,ostream_iterator<int>(cout," "));
	cout<<endl;

	//删除序列残余的元素
	coll.erase(pos,coll.end());

	//真正移除后的序列
	copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	//下面介绍---直接删除的标准方法(也适用于deque,同时也适用于list,但是list的成员函数remove更高效)
    cout<<"coll1:"<<endl;

	vector<int> coll1(data,data+10);
	//deque<int> coll1(data,data+10);
	//list<int> coll1(data,data+10);

	//原序列
	copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	//删除
	coll1.erase(remove(coll1.begin(),coll1.end(),1),coll1.end());

	//删除后序列
	copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	//下面测试list的成员函数remove和算法remove
	cout<<"coll2:"<<endl;

	list<int> coll2;

	for(int i=0;i<(sizeof(data)/sizeof(data[0]));i++)
	{
		coll2.push_back(data[i]);
	}

	//原序列
	copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	coll2.remove(1);

	//删除后序列
	copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," "));
	cout<<endl;

	system("pause");
	return 0;
}

remove_if:

移除[first,last)区间内所有被仿函数pred核定为true的元素。它和remove一样,并不真正从容器中删除那些元素,每一个不符合pred条件的元素都会被轮番赋给first之后的空间。
返回值ForwardIterator标示出重新整理后的最后元素的下一位置。此算法会留有一些残余数据,如果要删除那些残余数据,可将返回的迭代器交给区间所在之容器earse() member function。

remove_copy_if:

移除[first,last)区间内所有被仿函数pred评估为true的元素。它并不是真正从容器中删除那些元素(换句话说原容器没有任何改变),而是将结果复制到一个以result标示起始位置的容器身上。
新容器可以和原容器重叠,但如果针对新容器实际给值时,超越了旧容器的大小,会产生无法预期的结果。返回值OutputIterator指出被复制的最后元素的下一位置。


STL源码:

template<class ForwardIterator,class Predicate>
ForwardIterator remove_if(ForwardIterator first,ForwardIterator last,Predicate pred)
{
     first=find_if(first,last,pred);
	 ForwardIterator next=first;

	 return first==last?first:remove_copy_if(++next,last,first,pred);
}

template<class InputIteartor,class OutputIterator,class Predicate>
OutputIterator remove_copy_if(OutputIterator first,OutputIterator last,OutputIterator result,Predicate pred)
{
    for(;first!=last;++first)
	{
	    if(!pred(*first))
		{
	       *result=*first;
		   ++result;
		}
	}
	return result;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值