C++ Primer 第10章泛型算法

10.1 概述

  • 大多数算法定义在algorithm中,标准库还在头文件numeric中定义了数值泛型算法
  • 一般情况下,这些算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围来进行操作。
  • find(迭代器1.cbegin(),迭代器2.cend(),元素);当不能找到时,返回迭代器2.
  • 由于指针就像内置数组上的迭代器一样,使用标准库中的begin和end来获得数组中首元素和尾元素的指针也可以在数组中查找:
    find(begin(arr),end(arr),元素);# 10.2 初始泛型算法

算法如何工作

迭代器令算法不依赖与容器,。。。。

。。。。,但算法依赖于元素类型的操作

C++ Primer 第10章泛型算法_第1张图片

10.2 初始泛型算法

  • 除了少数例外,标准库算法都对一个范围内的元素进行操作。称此范围为输入范围
  • 理解算法最基本的方法就是了解他们是否读取元素,改变元素,重排元素

10.2.1 只读算法

  • 例如find函数和count函数
  • accumulate函数(begin,end,和的初值).
    accumulate的第三个参数的类型决定了函数中使用那个加法运算符已经返回值的类型

算法和元素类型

C++ Primer 第10章泛型算法_第2张图片

操作两个序列的算法

  • equal:接受三个迭代器,前两个表示第一个序列中的元素范围,第三个表示第二个序列的首元素
  • 由于利用迭代器完成操作,因此我们可以通过调用equal来比较不同类型的容器中的元素。元素类型可以不必一样,只要我们能用==来比较两个元素类型即可。例如string和const char*

那些只接受一个单一迭代器来表示第二个序列的算法,都假定第二个序列至少与第一个序列一样长

  • equal(roster1.cbegin(),roster1.cend(),roster2.cbegin());
    如果roster都是C分格的字符串即const char *则用==比较两个char对象,只是检查两个指针值是否相等,即地址是否相等而不是其中字符是否相同

10.2.2 写容器元素的算法

  • 算法不会执行容器操作,因此他们自身不可能改变容器的大小
    C++ Primer 第10章泛型算法_第3张图片

算法不检查写操作

  • fill_n:写入指定元素

介绍back_inster

C++ Primer 第10章泛型算法_第4张图片

拷贝算法

C++ Primer 第10章泛型算法_第5张图片

课后题

C++ Primer 第10章泛型算法_第6张图片

	list ilst = {1,2,3,4};
	fill_n(ilst.begin(), ilst.size(), 0);
  • a程序中进行缺省初始化,但是vec为空,copy无法进行,如需改变容器大小,需要使用一类特殊的称为插入器的迭代器。将第三个参数改为back_insterter(vec);
    C++ Primer 第10章泛型算法_第7张图片
    C++ Primer 第10章泛型算法_第8张图片

10.2.3 重排容器元素的算法

C++ Primer 第10章泛型算法_第9张图片
在这里插入图片描述
C++ Primer 第10章泛型算法_第10张图片

10.3 定制操作

10.3.1 向算法传递函数

谓词

  • 是一个可调用的表达式,其返回结果是一个能用作条件的值

C++ Primer 第10章泛型算法_第11张图片
C++ Primer 第10章泛型算法_第12张图片

10.3.2 lambda表达式

在这里插入图片描述

  • 尾置返回 auto GetType() -> int;
    在这里插入图片描述

向lambda传递参数

  • lambada不能有默认参数
    C++ Primer 第10章泛型算法_第13张图片

使用捕获列表

  • 一个labbda通过即将局部变量包含在其捕获列表中来指出将会使用这些变量。
  • 一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数中使用该变量
    C++ Primer 第10章泛型算法_第14张图片

for_each算法

C++ Primer 第10章泛型算法_第15张图片
C++ Primer 第10章泛型算法_第16张图片

10.3.3 lambda捕获和返回

  • 当定义一个lambda时,编译器生成一个与lambda对应的新的(未命名的)类类型。可以这样理解,当向一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象。
    C++ Primer 第10章泛型算法_第17张图片

值捕获

  • 采用值捕获的前提是变量可以拷贝。与参数不同,被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝。
    C++ Primer 第10章泛型算法_第18张图片

引用捕获

  • 采用引用捕获必须确保被引用的对象在lambda执行的时候是存在的。lambda捕获的都是局部变量,这些变量在函数结束之后就不存在了。
  • 我们也可以从一个函数返回一个lambda。但此lambda不能包含引用捕获

C++ Primer 第10章泛型算法_第19张图片

隐式捕获

  • 为了指示编译器推断捕获列表,应在捕获列表中写一个&或=。前者告诉编译器采用捕获引用方式,后者表示采用值捕获方式。
    C++ Primer 第10章泛型算法_第20张图片

可变lambda

C++ Primer 第10章泛型算法_第21张图片

指定lambda返回类型

C++ Primer 第10章泛型算法_第22张图片

10.3.4 参数绑定

C++ Primer 第10章泛型算法_第23张图片

绑定check_size的sz参数

C++ Primer 第10章泛型算法_第24张图片

使用placeholders名字

C++ Primer 第10章泛型算法_第25张图片

bind参数

C++ Primer 第10章泛型算法_第26张图片

用bind重排参数顺序

C++ Primer 第10章泛型算法_第27张图片

绑定引用参数

C++ Primer 第10章泛型算法_第28张图片

10.4 再探迭代器

C++ Primer 第10章泛型算法_第29张图片

10.4.1 插入迭代器

C++ Primer 第10章泛型算法_第30张图片
C++ Primer 第10章泛型算法_第31张图片

10.4.2 iostream迭代器

C++ Primer 第10章泛型算法_第32张图片

istream_iterator操作

C++ Primer 第10章泛型算法_第33张图片
C++ Primer 第10章泛型算法_第34张图片

使用算法操作流迭代器

C++ Primer 第10章泛型算法_第35张图片

istream_iterator允许使用懒惰求值

C++ Primer 第10章泛型算法_第36张图片

ostream_iterator操作

C++ Primer 第10章泛型算法_第37张图片

使用流迭代器处理类类型

C++ Primer 第10章泛型算法_第38张图片

10.4.3 使用反向迭代器

C++ Primer 第10章泛型算法_第39张图片

反向迭代器需要递减运算符

在这里插入图片描述

反向迭代器与其他迭代器之间的关系

C++ Primer 第10章泛型算法_第40张图片
C++ Primer 第10章泛型算法_第41张图片

10.5 泛型算法结构

C++ Primer 第10章泛型算法_第42张图片

10.5.1 5类迭代器

C++ Primer 第10章泛型算法_第43张图片

迭代器类别

输入迭代器

C++ Primer 第10章泛型算法_第44张图片

输出迭代器

C++ Primer 第10章泛型算法_第45张图片

前向迭代器

在这里插入图片描述

双向迭代器

在这里插入图片描述

随机访问迭代器

C++ Primer 第10章泛型算法_第46张图片

10.5.2 算法形参模式

C++ Primer 第10章泛型算法_第47张图片

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

C++ Primer 第10章泛型算法_第48张图片

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

C++ Primer 第10章泛型算法_第49张图片

10.5.3 算法命名规范

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

C++ Primer 第10章泛型算法_第50张图片

_if版本的算法

C++ Primer 第10章泛型算法_第51张图片

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

C++ Primer 第10章泛型算法_第52张图片

10.6 特定容器算法

C++ Primer 第10章泛型算法_第53张图片

splice成员

C++ Primer 第10章泛型算法_第54张图片

链表特有的操作会改变容器

C++ Primer 第10章泛型算法_第55张图片

你可能感兴趣的:(算法,c++,java)