STL::算法::常见算法(二)

STL::算法::常见算法

remove_copy/remove 及其泛化版 remove_copy_if/remove_if

这两组函数提供的实现删除序列中的相关元素的思路,对我们实现自己的算法是有帮助的。

这四个函数所在的头文件仍然是#include <algorithm>

  • remove 需调用 remove_copy 才能实现自身的功能
  • remove_if 则需调用 remove_copy_if 实现自身的功能
  • remove_if 是 remove 的泛化版本,也即 remove 使用的是“相等(equality)条件”,remove_if 则是根据参数中指定的某一断言(predicate)为条件

尤其需要注意的是,这四个函数虽然函数名都有 remove,但均没有移除容器元素的动作,也即至少均不改变容器的大小,更有甚者 remove_copy/remove_copy_if 甚至不会对原容器做任何改变。

remove/remove_if 更像是一种对序列的重新整理,将残余元素置于序列的尾部,返回指向第一个残余元素的迭代器,故只需将 remove/remove_if 函数与容器的 erase() 成员函数相结合时,才会真正删除容器中等于某值(remove)或符合某一条件(remove_if)的元素。最后我们会给出一个删除容器中所有偶数的操作。

  • remove_copy

    移除 [first, last) 区间内所有与 value相等的元素,它并不真正从容器中删除那些元素,而是将结果复制(copy)到一个以result标示起始位置的容器身上(也即可以对原始容器没有任何改变,如果result不在[first, last)的区间内)。新容器可以和原容器重叠(remove 便是如此)

    template<class InputIterator, class OutputIterator, class T>
    OutputIterator remove_copy(InputIterator first, InputIterator last, 
                        OutputIterator result, const T& value)
    {
        for (; first < last; ++first)
        {
            if (*first != *result) { *result = *first; ++result; } } return result; }
  • remove:移除,但不删除,残余元素置于容器的最后

    所以很方便coll.erase(std::remove(...), coll.end()),真正地移除无关数据。

    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_if

    template<typename InputIterator, typename OutputIterator, typename Pred>
    OutputIterator remove_copy_if(InputIterator first, InputIterator last,
                            OutputIterator result, Pred pred)
    {
        for (; first < last; ++first)
        {
            if (!pred(*first))
            {
                *result = *first;
                ++result;
            }
        }
        return result;
    }
  • remove_if

template<typename ForwardIterator, typename Pred>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Pred pred)
{
    first = std::find_if(first, last, pred);
    ForwardIterator next = first;
    return first == last ? first : remove_copy_if(++next, last, first, pred);
    // return remove_copy_if(first, last, first, pred);

}
  • 一个实例

    移除序列中的偶数

std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
v.erase(std::remove_if(v.begin(), v.end(), [=](int x){ return x%2 == 0;}), v.end());

你可能感兴趣的:(STL::算法::常见算法(二))