STL之remove算法详解

来源:互联网 发布:淘宝助理设置快递模板 编辑:程序博客网 时间:2024/05/23 12:43

算法描述

接口

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,确保真正的删除!

1 0
原创粉丝点击