算法描述
接口
template<class ForwardIterator, class Type> ForwardIterator remove( ForwardIterator _First, ForwardIterator _Last, const Type& _Val );
功能
将一个指定的值从指定的区间中[first,last)“删除”,这里的“删除”是指:把区间内”指定值”的位置腾出,用copy的方式把后面”非指定值”逐一的往前移动。
比如:
序列(1234)remove 2后,返回的序列是 1344(3被复制到2的位置,4被复制到3的位置)。
原理
第一层算法:
template<class _FwdIt, class _Ty> inline _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val) { // remove each matching _Val _First = find(_First, _Last, _Val); if (_First == _Last) { return (_First);// empty sequence, all done } else { // nonempty sequence, worth doing _FwdIt _First1 = _First; return (_STDEXT unchecked_remove_copy(++_First1, _Last, _First, _Val)); } }
最底层算法:
/****************************************************** **_First:第一个待删除值的下一个位置 **_Last:指向目标容器最后一个元素的下一个位置 ** _Val:待删除的值 **_Dest:返回值,初始值为目标容器的第一个指定位置 *********************************************************/ template<class _InIt, class _OutIt, class _Ty> inline _OutIt _Remove_copy(_InIt _First, _InIt _Last, _OutIt _Dest, const _Ty& _Val, _Range_checked_iterator_tag) { //copy omitting each matching _Val for (; _First != _Last; ++_First) { if (!(*_First == _Val)) { *_Dest++ = *_First; } } return (_Dest); }
特点
remove算法是稳定的,因为其他元素的相对位置并没有改变。同时remove算法并不能直接的删除特定元素,因此目标的容器大小不变。
算法应用
源码
#include "stdafx.h" #include <string.h> #include <algorithm> #include <vector> #include <deque> #include <functional> #include <iostream> #include <list> #include <iterator> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { vector<int> vecContainer; const int nLoop = 5; for (int i = 0; i < nLoop; ++i) { vecContainer.push_back(i); } vecContainer.insert(vecContainer.end(), 2); vecContainer.insert(vecContainer.end(), 5); vecContainer.insert(vecContainer.end(), 6); //0 1 2 3 4 2 5 6 vector<int> vecData(vecContainer); cout <<"before remove:"<<endl; copy(vecContainer.begin(), vecContainer.end(), ostream_iterator<int>(cout," ")); cout << endl; cout <<"after remove:"<<endl; remove(vecContainer.begin(), vecContainer.end(), 2); copy(vecContainer.begin(), vecContainer.end(), ostream_iterator<int>(cout," ")); cout << endl; //需要使用备份后的vecData cout <<"after erase:"<<endl; //推荐用法 vecData.erase(remove(vecData.begin(),vecData.end(), 2), vecData.end()); copy(vecData.begin(), vecData.end(), ostream_iterator<int>(cout," ")); cout<<endl; return 0; }
内存变化过程
运行结果
结论:使用remove删除成员后需要立即调用erase,确保真正的删除!
来源:https://www.cnblogs.com/jinxiang1224/p/8468434.html