zoukankan      html  css  js  c++  java
  • 泛型算法结构

    算法要求的迭代器操作可以分为5个迭代器类别,每个算法都会对它的每个迭代器参数指明须提供哪类迭代器:

    5类迭代器

    一些操作所有迭代器都支持,另外一些只有特定类别的迭代器才支持:ostream_iterator 只支持递增、解引用和赋值,vectorstringdeque 迭代器除了这些操作外,还支持递减、关系、算术运算。

    输入迭代器

    输入迭代器可以读取序列中的二元素,一个输入迭代器必须支持:

    • 用于比较两个迭代器的相等和 不相等运算符(==!=)。
    • 用于推进迭代器的前置和后置递增运算(++)。
    • 用于读取元素的解引用运算符(*);解引用只会出现在赋值运算符的右侧。
    • 箭头运算符(->),等价于*(it).member,即,解引用迭代器,并提取对象 的成员。

    输入迭代器只用于单遍扫描算法,算法 findaccumulate 要求输入迭代器;istream_iterator 是一种输入迭代器。

    输出迭代器

    输出迭代器可以看作输入迭代器上的补集,只写而不读元素,输出迭代器必须支持:

    • 用于推进迭代器的前置和后置递增运算(++)。
    • 解引用运算符(*),只出现在赋值运算符的左侧(向一个已经解引用的输出迭代器赋值,就是将值写入它所指向的元素)。

    只能向一个输出迭代器赋值一次,类似输入迭代器,输出迭代器只能用于单遍扫描算法。用作目的位置的迭代器通常都是输出迭代器,例如:copy 函数的第三个参数就是输出迭代器,ostream_iterator 类型也是输出迭代器。

    前向迭代器

    前向迭代器可以读写元素,这类迭代器只能在序列中沿一个方向移动。前向迭代器支持所有输入和输出迭代器操作,而且可以多次读写同一个元素。

    可以保存前向迭代器的状态,使用前向迭代器的算法可以对序列进行多遍扫描。算法 replace 要求前向迭代器,forward_list 上的迭代器是前向迭代器。

    双向迭代器

    双向迭代器可以正向/反向读写序列中的元素。除了支持所有前向迭代器的操作之外,双向迭代器还支持前置和后置的递减操作符(--)。算法 reverse 要求双向迭代器,除了 forward_list 之外,其它标准库都提供符合双向迭代器要求的迭代器。

    随机访问迭代器

    随机访问迭代器提供在常量时间内访问序列中任意元素的能力。此类迭代器支持双向迭代器的所有功能:

    • 用于比较两个迭代器相对位置的关系运算符(<<=>>=)。
    • 迭代器和一个整数值的加减运算(++= - -=),计算结果是迭代器在序列中前进或后退给定整数个元素后的位置。
    • 用于两个迭代器上减法运算符(-),得到两个迭代器的距离。
    • 下标运算符 (iter[n]),与 *(iter[n]) 等价。

    算法 sort 要求随机访问迭代器。arraydequestringvector 的迭代器都是随机访问迭代器,用于访问内置数组元素的指针也是。

    算法形参模式

    大多数算法具有如下四种形式之一:

    alg(beg, end, other args);
    alg(beg, end,dest, other args);
    alg(beg, end, beg2,other args);
    alg(beg, end, beg2, end2, other args);
    

    alg 表示算法的名字,begend 表示算法所操作的输入范围,几乎所有的算法都接受一个输入范围,是否有其他参数依赖于要执行的操作。dest 表示指定的目的位置,beg2end2 表示第二个范围。

    接受单个目标迭代器的算法

    向输出迭代器写入数据的算法都假定目标空间足够容纳写入的数据。

    如果 dest 是一个直接指向容器的迭代器,那么算法将输出数据写到容器中已存在的元素内,更常见的情况,dest 被绑定到一个插入迭代器或者是一个 ostream_iterator。插入迭代器会将新元素添加到容器中,因而保证空间是足够的。ostream_iterator 会将数据写入到一个输出流,同样不管要写入多少个元素都没有问题。

    接受第二个输入序列的算法

    接受单独的 beg2 或是接受 beg2end2 的算法用这些迭代器表示第二个输入范围。这些算法通常使用第二个范围中的元素与第一个输入范围结合来进行一些运算。

    只接受单独的 beg2 的算法将 beg2 作为输入范围中的首元素,此范围的结束为止未指定,这些算法假定从 beg2 开始的范围与从 begend 所表示的范围至少一样大。

    如果算法接受 beg2end2,这两个迭代器表示第二个范围,这类算法接受两个完整指定的范围:[beg,end) 范围和 [beg2,end2) 的第二个范围。

    算法命名规范

    一些算法使用重载形式传递一个谓词。

    接受谓词参数来代替 <= 运算符的算法,以及那些不接受额外参数的算法,通常都是重载的函数。函数的一个版本用元素类型的运算符来比较元素;另一个版本接受一个额外谓词参数,来代替 <=

    unique(behg,end); //使用 == 运算符比较元素
    unique(behg,end,comp); //使用 comp 比较元素
    

    两个调用都重新整理给定序列,将相邻的重复元素删除。

    _if 版本的算法

    接受一个元素值的算法通常有另一个不同名的(不是重载的)版本,该版本接受一个谓词代替元素值,接受谓词参数的算法都有附加的 _if 前缀:

    find(beg,end,val);	//查找输入范围中val第一次出现的位置
    find_if(beg,end,pred);	//查找第一个令pred位置的元素
    

    这两个算法都在输入范围中查找特定元素第一次出现的位置。

    算法 find 查找一个指定的值,算法 find_if 查找使得 pred 返回非零值的元素。

    区分拷贝元素的版本和不拷贝的版本

    默认情况下,重排元素的算法重排后的元素写回给定的输入序列中。这些算法还提供另一个版本,将元素写到一个指定的输出目的位置。写到额外目的空间的算法都在名字后面附加一个 _copy

    reverse(beg,end);	//反转输入范围中元素的顺序
    reverse_copy(beg,end,dest);	//将元素按逆序拷贝到dest
    

    一些算法同时提供 _copy_if 版本,这些版本接受一个目的位置迭代器和一个谓词:

    //从v1中删除奇数元素
    remove_if(v1.begin(),v1.end(),[](int i){return i % 2;});
    //将偶元素从v1拷贝到v2;v1不变
    remove_copy_if(v1.begin(),v1.end(),back_inserter(v2),[](int i){ i % 2;});
    
  • 相关阅读:
    20150607-0608
    20150423
    感触
    NSString里面的数字
    Git使用相关
    状态栏的设置
    UI相关问题
    分栏(标签)控制器
    导航控制器
    NSAttributedString 属性
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/12497100.html
Copyright © 2011-2022 走看看