zoukankan      html  css  js  c++  java
  • [GeekBand] STL与泛型编程(3)

    本篇文章主要介绍泛型算法中的变易、排序、数值算法。

    一、 变易算法

    所谓变易算法是指那些改变容器中的对象的操作。

    1.1 copy组

    template <class InputIterator, class OutputIterator>

    OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

    Copy操作是将两个输入迭代器之间的元素拷贝到输出迭代器处。注意拷贝时采用的是左对齐,会发生覆盖,使用时应该确保容器具有足够的大小,或者使用inserter迭代器。注意,由于采用的是左对齐的方式,可以实现向量元素的左移。

    template <class BidirectionalIterator1, class BidirectionalIterator2>

    BidirectionalIterator2 copy_backward (BidirectionalIterator1 first,

    BidirectionalIterator1 last,

    BidirectionalIterator2 result);

    与普通的copy对应的,有一种右对齐的拷贝方式copy_backward,指定的输出迭代器为拷贝的末地址。

    template <class InputIterator, class OutputIterator>

    OutputIterator copy_n (InputIterator first, int num, OutputIterator result);

    也可以采用起始迭代器和个数进行拷贝。

    template <class InputIterator, class OutputIterator, class UnaryPredicate>

    OutputIterator copy_if (InputIterator first, InputIterator last,

    OutputIterator result, UnaryPredicate pred);

    也可以进行if条件的筛选,pred参数可以是函数指针,函数对象,也可以采用匿名函数。

     

    1.2 swap组

    template <class T> void swap (T& a, T& b);

    Swap操作将a,b两个容器(不是迭代器)中的元素交换。

    template <class ForwardIterator1, class ForwardIterator2>

    ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,

    ForwardIterator2 first2);

    也可以采用元素区间的方式进行交换。注意这里要求,第一个区间要小于第二个区间。函数的操作是将第一个区间的全部n个元素和第二个区间的前n个元素交换。也就是说,第二个区间后边的元素不会被改变。

    1.3 transform

    template <class InputIterator, class OutputIterator, class UnaryOperation>

    OutputIterator transform (InputIterator first1, InputIterator last1,

    OutputIterator result, UnaryOperation op);

    Transform会把容器中的元素进行相应的"转换",将每个元素丢给op函数进行操作,返回值存到result开始 位置中。如果result == first1,就是完整的转换操作。

    template <class InputIterator1, class InputIterator2,

    class OutputIterator, class BinaryOperation>

    OutputIterator transform (InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, OutputIterator result,

    BinaryOperation binary_op);

    这种重载的特点是,最后的操作不再是一个单参操作,而是双参操作。其第一个参数是first1到last1之间的每一个元素,而第二个参数则从first2开始,一一对应的进行选择。

    1.4 replace组

    template <class ForwardIterator, class T>

    void replace (ForwardIterator first, ForwardIterator last,

    const T& old_value, const T& new_value);

    普通的replace操作是,对于区间内的操作,如果等于old_value,则将其替换为新的值。

    template <class ForwardIterator, class UnaryPredicate, class T>

    void replace_if (ForwardIterator first, ForwardIterator last,

    UnaryPredicate pred, const T& new_value );

    也可以进行需要函数判断替换的replace_if操作,将区间内的每个元素扔给函数对象,如果返回值为真则进行替换。

    template <class InputIterator, class OutputIterator, class T>

    OutputIterator replace_copy (InputIterator first, InputIterator last,

    OutputIterator result,

    const T& old_value, const T& new_value);

    Replace_copy操作是将区间内的元素先复制到目的迭代器指定的位置处,注意目的迭代器的容量问题。随后,并且对目的迭代器中的这些元素进行替换操作。

    template <class InputIterator, class OutputIterator, class T>

    OutputIterator replace_copy_if (InputIterator first, InputIterator last,

    OutputIterator result,

    UnaryPredicate pred, const T& new_value);

    Replace_copy_if操作就是replace_if的带复制版本。

    1.5 fill

    template <class ForwardIterator, class T>

    void fill (ForwardIterator first, ForwardIterator last, const T& val);

    将区间内的元素直接用这个值进行填充。

    1.6 generate

    template <class ForwardIterator, class Generator>

    void generate (ForwardIterator first, ForwardIterator last, Generator gen);

    将无参函数gen的返回值放在区间内。通常用于产生随机数,例如:

    Generate(v.begin(),v.end(),rand);

    1.7 remove组

    template <class ForwardIterator, class T>

    ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);

    Remove检查区间内的元素,如果相等,则将这个元素删除,最后返回一个迭代器,指向这个被删除后的区间中最后的元素。也就是说,如果原本最后一个元素没有被删除,则指向原本的最后一个元素;如果原本的最后一个元素也被删除了,则往前移动。

    template <class ForwardIterator, class UnaryPredicate>

    ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,

    UnaryPredicate pred);

    在普通remove的基础上,通过检验判别函数(单参数 )决定是否remove。

    template <class InputIterator, class OutputIterator, class T>

    OutputIterator remove_copy (InputIterator first, InputIterator last,

    OutputIterator result, const T& val);

    在普通remove的基础上,改为先将其复制到新的位置,再对新的容器进行remove操作。

    1.8 unique

    template <class ForwardIterator>

    ForwardIterator unique (ForwardIterator first, ForwardIterator last);

        

    template <class ForwardIterator, class BinaryPredicate>

    ForwardIterator unique (ForwardIterator first, ForwardIterator last,

    BinaryPredicate pred);

    Unique操作,第一种形式是将相同的元素删除,只保留一份,返回的迭代器和remove操作一样;第二种是通过一个pred函数的返回值来查看是否是一样的,从中可以建立映射。

    1.8 reverse

    template <class BidirectionalIterator>

    void reverse (BidirectionalIterator first, BidirectionalIterator last);

    Reverse函数将容器首位倒置,即"123"->"321";

    1.9 rotate

    template <class ForwardIterator>

    void rotate (ForwardIterator first, ForwardIterator middle,

    ForwardIterator last);

    Rotate即翻转操作,以middle为界,把middle前边的元素都移到最末尾,middle成为新的区间头。

    1.9 random_shuffle

    generator by default (1)    

    template <class RandomAccessIterator>

    void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);

     

    specific generator (2)    

    template <class RandomAccessIterator, class RandomNumberGenerator>

    void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,

    RandomNumberGenerator& gen);

    Shuffle即洗牌操作;将元素进行打乱。当进行自定操作时,则可能是N的阶乘中情况中的任何一种。当自定义操作时候,其行为是依次将第i号元素和第gen(i)号元素进行交换,一直到容器底。

    1.10 partition

    template <class BidirectionalIterator, class UnaryPredicate>

    BidirectionalIterator partition (BidirectionalIterator first,

    BidirectionalIterator last, UnaryPredicate pred);

    Partition的行为是按照pred的返回值的true或false进行划分。划分后返回的迭代器result,使得[r.begin(),result )为true,[result,r.end())为false。

    二、    排序算法

    2.1    普通排序

    2.1.1 sort

    default (1)    

    template <class RandomAccessIterator>

    void sort (RandomAccessIterator first, RandomAccessIterator last);

    custom (2)    

    template <class RandomAccessIterator, class Compare>

    void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

    Sort有两种形式,第一重型是默认是调用了operator<函数进行比较,小者在前,也可以自行指定,两两相比返回值为1的元素在前。

    2.1.2 partial_sort

    default (1)    

    template <class RandomAccessIterator>

    void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,

    RandomAccessIterator last);

    custom (2)    

    template <class RandomAccessIterator, class Compare>

    void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,

    RandomAccessIterator last, Compare comp);

    进行部分排序,使得first到middle的元素是有序的,而middle到end的元素是打乱的(具体顺序不定)。这个排序可以用来找到前n大或者前n小的元素。例如,原来v中的元素为3,2,1,4,5,1,0;调用partial_sort(v.begin(),v.begin+4,v.end())后,结果是[0,1,1,2,…..(顺序不定)]

    2.1.3 binary_search

    default (1)    

    template <class ForwardIterator, class T>

    bool binary_search (ForwardIterator first, ForwardIterator last,

    const T& val);

    custom (2)    

    template <class ForwardIterator, class T, class Compare>

    bool binary_search (ForwardIterator first, ForwardIterator last,

    const T& val, Compare comp);

    在排好序的情况下,进行二分搜索,查找值为val的元素。元素必须先手动排序。

    2.1.4 merge

    default (1)    

    template <class InputIterator1, class InputIterator2, class OutputIterator>

    OutputIterator merge (InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, InputIterator2 last2,

    OutputIterator result);

    custom (2)    

    template <class InputIterator1, class InputIterator2,

    class OutputIterator, class Compare>

    OutputIterator merge (InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, InputIterator2 last2,

    OutputIterator result, Compare comp);

    将两个已经排好的序列进行快速有序合并。

    2.2 集合排序算法

    2.2.1 includes

    template <class InputIterator1, class InputIterator2>

    bool includes ( InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, InputIterator2 last2 );

     

    template <class InputIterator1, class InputIterator2, class Compare>

    bool includes ( InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, InputIterator2 last2, Compare comp );

    检查一个有序区间1内是否包含另一个有序区间2内的元素,注意如果排序方法不是operator <,则必须要显式的声明出来。所谓的包含是指,12345中包含了125,1234321包含了33,并不要求连续。

    2.2 堆排序算法

    2.2.1 make_heap

    default (1)    

    template <class RandomAccessIterator>

    void make_heap (RandomAccessIterator first, RandomAccessIterator last);

    custom (2)    

    template <class RandomAccessIterator, class Compare>

    void make_heap (RandomAccessIterator first, RandomAccessIterator last,

    Compare comp );

    生成一个堆,默认情况下采取operator<进行比较,生成一个大顶堆;如果进行大于比较,则是生成小顶堆。

    这种堆在存储时采用从上到下,从左至右的方式进行存储。

    2.2.2 push_heap

    default (1)    

    template <class RandomAccessIterator>

    void push_heap (RandomAccessIterator first, RandomAccessIterator last);

    custom (2)    

    template <class RandomAccessIterator, class Compare>

    void push_heap (RandomAccessIterator first, RandomAccessIterator last,

    Compare comp);

    Push_heap操作向堆中添加元素,并对其进行调整。其调整方法为先将其放到整个堆的末尾,然后再向前进行逐次交换。由于前面的元素都满足平衡二叉树的条件,这种方法的正确性得以保证。

    2.2.3 pop_heap

    default (1)    

    template <class RandomAccessIterator>

    void pop_heap (RandomAccessIterator first, RandomAccessIterator last);

    custom (2)    

    template <class RandomAccessIterator, class Compare>

    void pop_heap (RandomAccessIterator first, RandomAccessIterator last,

    Compare comp);

    从堆顶弹出一个元素。对于大顶堆,则代表弹出最大元素。弹出后重新调整为平衡二叉树的方法是,先将其和整个堆末尾的元素进行一次交换,然后将其删除。随后,让新的根顶元素逐次向下比较交换,每次都与子节点中比自己大的较大者交换,知道这一节点大于其子节点或是不存在子节点。采用这种交换的方式,保证了平衡二叉树的紧密,而且具有logn的时间复杂度。

    2.2.4 sort_heap

    default (1)    

    template <class RandomAccessIterator>

    void sort_heap (RandomAccessIterator first, RandomAccessIterator last);

    custom (2)    

    template <class RandomAccessIterator, class Compare>

    void sort_heap (RandomAccessIterator first, RandomAccessIterator last,

    Compare comp);

    利用出堆操作对堆进行排序。

    三、 泛型数值算法

    1.1 accumulate

    sum (1)    

    template <class InputIterator, class T>

    T accumulate (InputIterator first, InputIterator last, T init);

    custom (2)    

    template <class InputIterator, class T, class BinaryOperation>

    T accumulate (InputIterator first, InputIterator last, T init,

    BinaryOperation binary_op);

    Accumulate操作是以init为初始值,和每个成员进行操作。默认情况下的操作为+=,也就是累加运算。如果指定了一个操作函数,那么每次操作result = op(*it,result);注意第一参数为容器元素。

    例如,求1+…+100可以采用以下代码:

    vector<int> v(100);

    iota(v.begin(),v.end(),1);//iota函数的作用是,以第三个参数为起始值,以递增1方式填满整个区间。

    int sum = accumulate(v.begin(),v.end(),0);

     

    1.2 inner_product

    sum/multiply (1)    

    template <class InputIterator1, class InputIterator2, class T>

    T inner_product (InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, T init);

    custom (2)    

    template <class InputIterator1, class InputIterator2, class T,

    class BinaryOperation1, class BinaryOperation2>

    T inner_product (InputIterator1 first1, InputIterator1 last1,

    InputIterator2 first2, T init,

    BinaryOperation1 binary_op1,

    BinaryOperation2 binary_op2);

    Inner_product是向量内积操作,例如,给定向量a[2] = {1,2};b[2] = {3,4};则默认情况下,返回值为1*3+2*4;自定义的方式下,则op2表示按位置一一对应时进行何种运算,而op1则表示对这些所有结果进行何种运算。例如,若使用inner_product(a,a+3,b,1,multiplies<int>(),plus<int>());则计算1*(1+3)*(2+4)的结果。

    1.3 partial_sum

    sum (1)    

    template <class InputIterator, class OutputIterator>

    OutputIterator partial_sum (InputIterator first, InputIterator last,

    OutputIterator result);

    custom (2)    

    template <class InputIterator, class OutputIterator, class BinaryOperation>

    OutputIterator partial_sum (InputIterator first, InputIterator last,

     

    一种zigzag形式的运算,如图所示,对1,2,3,4,5进行此种运算的过程是:

    可以看到,产生的结果是一组数据,每一个数据都是前n个数据的累计。

    1.4 adjacent_difference

    difference (1)    

    template <class InputIterator, class OutputIterator>

    OutputIterator adjacent_difference (InputIterator first, InputIterator last,

    OutputIterator result);

    custom (2)    

    template <class InputIterator, class OutputIterator, class BinaryOperation>

    OutputIterator adjacent_difference ( InputIterator first, InputIterator last,

    OutputIterator result, BinaryOperation binary_op );

    这个函数对相邻两个元素进行运算,第一个元素不动。默认情况下采取减操作,如图:

    注意自行指定函数时,第一运算数为后边的元素。

  • 相关阅读:
    ASP.NET Web API 框架研究 Self Host模式下的消息处理管道
    ASP.NET Web API 框架研究 Web Host模式下的消息处理管道
    ASP.NET Web API 框架研究 核心的消息处理管道
    ASP.NET Web API 框架研究 Web Host模式路由及将请求转出到消息处理管道
    ASP.NET Web API 框架研究 ASP.NET Web API 路由
    ASP.NET Web API 框架研究 ASP.NET 路由
    ASP.NET Web API 入门 (API接口、寄宿方式、HttpClient调用)
    MVVM模式
    RESTful Web API 理解
    C# 函数式编程及Monads.net库
  • 原文地址:https://www.cnblogs.com/shawnChi/p/5829217.html
Copyright © 2011-2022 走看看