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