根据元素值或某一准则,在一个区间内移除某些元素。这些算法并不能改变元素的数量,它们只是以逻辑上的思考,将原本置于后面的"不移除元素"向前移动,覆盖那些被移除元素而已。它们都返回新区间的逻辑终点(也就是最后一个”不移除元素"的下一个位置)
1.移除某些特定元素
移除某序列内的元素
- ForwardIterator remove( ForwardIterator beg, ForwardIterator end, const T& value) //移除区间[beg,end)中每个"与value相等"的元素。返回变动后序列的新逻辑终点(也就是最后一个未被移除元素的下一位置)。
- ForwardIterator remove_if( ForwardIterator beg, ForwardIterator end, UnaryPredicate op) //移除使op(elem)获得true的元素。
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> coll;
INSERT_ELEMENTS(coll,2,6);
INSERT_ELEMENTS(coll,4,9);
INSERT_ELEMENTS(coll,1,7);
PRINT_ELEMENTS(coll,"coll: ");
vector<int>::iterator pos;
pos=remove(coll.begin(),coll.end(),5);
PRINT_ELEMENTS(coll,"size not changed: ");
coll.erase(pos,coll.end());
PRINT_ELEMENTS(coll,"size changed:");
coll.erase(remove_if(coll.begin(),coll.end(),
bind2nd(less<int>(),4)),coll.end());
PRINT_ELEMENTS(coll,"<4 removed: ");
return 0;
}
复制时一并移除元素
- OutputIterator remove_copy( InputIterator sourceBeg, InputIterator sourceEnd, OutputItertor destBeg, const T& value) //将源[beg, end)内的所有元素复制到"以destBeg为起点"的目标区间去,并在复制过程中移除"与value相等"的所有元素。返回目标区间中最后一个被复制元素的下一个位置(也就是第一个未被覆盖的元素)
- OutputIterator remove_copy_if( InputIterator sourceBeg, InputIteratorSourceEnd, OutputIterator destBeg, UnaryPredicate op) //满足op(elem)为true的元素
- 注:不修改源区间,所有结果只反映在destBeg的目标区间,先移除,再复制。
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
list<int> coll1;
INSERT_ELEMENTS(coll1,1,6);
INSERT_ELEMENTS(coll1,1,9);
PRINT_ELEMENTS(coll1);
remove_copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," "),3);
cout<<endl;
remove_copy_if(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," "),
bind2nd(greater<int>(),4));
cout<<endl;
multiset<int> coll2;
remove_copy_if(coll1.begin(),coll1.end(),
inserter(coll2,coll2.end()),bind2nd(less<int>(),4));
PRINT_ELEMENTS(coll2);
return 0;
}
2.移除重复元素
移除连续重复元素
- ForwardIterator unique( ForwardIterator beg, ForwardIterator end) //移除区间[beg, end)连续重复的元素中的多余元素
- ForwardIterator unique( ForwardIterator beg, ForwardIterator end, BinaryPredicate op) //将每一个位于e之后的并使op(elem,e)结果为true的所有elem被移除。(e在elem前一个位置,e未被移除)
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int source[]={1,4,4,6,1,2,2,3,1,6,6,6,5,7,5,4,4};
int sourceNum=sizeof(source)/sizeof(source[0]);
list<int> coll;
copy(source,source+sourceNum,back_inserter(coll));
PRINT_ELEMENTS(coll);
list<int>::iterator pos;
pos=unique(coll.begin(),coll.end());
copy(coll.begin(),pos,ostream_iterator<int>(cout," "));
cout<<"\n\n";
copy(source,source+sourceNum,coll.begin());
PRINT_ELEMENTS(coll);
coll.erase(unique(coll.begin(),coll.end(),greater<int>()),coll.end());
PRINT_ELEMENTS(coll);
return 0;
}

复制过程中移除重复元素(copy()和unique()的组合)
- OutputIterator unique_copy( InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg) //将源区间[beg,end)内的元素复制到”以destBeg起始的目标区间",并移除重复元素。返回目标区间内"最后 一个被复制的元素"的下一位置。
- OutputIterator unique_copy( InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, BinaryPredicate op)
// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
bool differenceOne(int elem1, int elem2)
{
return (elem1+1==elem2)||(elem1-1==elem2);
}
int _tmain(int argc, _TCHAR* argv[])
{
int source[]={1,4,4,6,1,2,2,3,1,6,6,6,5,7,5,4,4};
int sourceNum=sizeof(source)/sizeof(source[0]);
list<int> coll;
copy(source,source+sourceNum,back_inserter(coll));
PRINT_ELEMENTS(coll);
unique_copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "));
cout<<endl;
unique_copy(coll.begin(),coll.end(),ostream_iterator<int>(cout," "),
differenceOne);
cout<<endl;
return 0;
}

// STL.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <print.hpp>
#include <iostream>
using namespace std;
bool bothspaces(char elem1, char elem2)
{
return elem1==' ' && elem2==' ';
}
int _tmain(int argc, _TCHAR* argv[])
{
cin.unsetf(ios::skipws); //默认cin会过滤空白(空格,表格键等)
// copy(istream_iterator<char>(cin),istream_iterator<char>(),
// ostream_iterator<char>(cout));
unique_copy(istream_iterator<char>(cin),
istream_iterator<char>(),ostream_iterator<char>(cout),bothspaces);
return 0;
}
