《C++ Primer》 读书笔记——第十章 泛型算法

第十章 泛型算法

10.1 概述

1、与泛型算法相关的头文件

大多数算法定义在头文件algorithm中
头文件numeric定义了数值泛型算法

2、算法不会执行容器操作

算法不执行容器操作(上一章介绍的容器函数),而是使用迭代器。
迭代器的使用令算法不依赖于容器类型(有些容器有这个函数,有些容器没有这个函数)

10.2 初始泛型算法

1、accumulate

设置和的初始值,计算给定范围内的和
在这里插入图片描述
它将第三个参数作为求和的起点,并且默认序列中元素的类型与第三个参数可以相加,并且类型兼容。

在这里插入图片描述

2、对于只读算法,最好使用常量类型的迭代器

在这里插入图片描述

3、equal

确定两个序列是否保存相同的值
在这里插入图片描述
要求第二个序列的长度大于等于第一个序列

4、fill

将给定值赋予范围中的每个元素
在这里插入图片描述

5、fill_n

fill的基地址+偏移版本
在这里插入图片描述
像这种向目的位置迭代器写入数据的算法假定目的位置足够大,能容纳要写入的元素。否则会发生灾难性错误

6、插入迭代器

back_inserter是定义在头文件iterator中的一个函数,通过它可以获取插入迭代器。
在这里插入图片描述
在这里插入图片描述

7、copy

将一个范围的值拷贝到另一个地方
在这里插入图片描述
在这里插入图片描述
返回值是拷贝目的地址的尾后迭代器end

8、replace及拷贝版本算法

replace读入一个序列,并将其中所有等于给定值的元素都改为另一个值
在这里插入图片描述
一般版本会直接替换原有序列中的值,这样会破坏源数据
而下面的拷贝版本则会将保存到新的序列中,原有序列则保持不变
在这里插入图片描述

9、sort

接受两个迭代器表示范围,按默认<的比较模式从小到大地排序
在这里插入图片描述
原序列:
在这里插入图片描述
排序后的序列:
在这里插入图片描述

10、unique

在这里插入图片描述
该函数重排输入序列,将不重复的值放在前面,重复的值放在后面。返回尾端第一个重复值的迭代器
在这里插入图片描述

10.3 定制操作

1、谓词

在这里插入图片描述
①、谓词版本的sort函数
在这里插入图片描述
sort函数会将满足函数isShorter要求的元素排在前面(返回true)

②、stable_sort 稳定排序函数
该算法维持相等元素原有顺序
在这里插入图片描述

2、lambda表达式

前置知识——调用运算符:
在这里插入图片描述
lambda表达式什么时候用?
在这里插入图片描述
①、介绍lambda
在这里插入图片描述
[捕获列表] (参数列表)-> 返回值类型 {函数体}

可以忽略参数列表和返回值类型,但是必须永远包含捕获列表函数体
在这里插入图片描述
②、lambda的调用
在这里插入图片描述
③、lambda的返回类型
在编写lambda时如果省略返回类型
当函数体中只存在一条返回语句时,会根据该返回语句自动推断返回类型
当函数体中存在除了返回语句之外的其它语句时,会默认返回void类型。

④、lambda的捕获列表
一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数体中使用该变量
在这里插入图片描述

3、for_each

在这里插入图片描述
对序列中的每个元素都调用此对象

4、再探lambda

①、lambda本身的类型
在这里插入图片描述
每定义一个新的lambda,就生成一个新的类型

②、捕获列表的方法

  1. 值捕获
    在这里插入图片描述

  2. 引用捕获
    在这里插入图片描述
    当使用引用捕获时,需要保证在使用lambda表达式时引用变量是存在的。
    并且当返回值是引用该引用值时,需要保证返回时引用变量也是存在的。

  3. 隐式捕获
    在这里插入图片描述

  4. 混合捕获
    在这里插入图片描述
    尽可能将捕获简单化
    在这里插入图片描述

5、参数绑定

①、定义
在这里插入图片描述
我的理解是相当于函数接口加了一层中间层,在中间层进行一些处理后显示给用户调用。
在这里插入图片描述
后面的参数列表对应的是callable里面的所需的参数。
返回值可以理解为一个中间层函数。一般给用户调用的也就是这个中间层函数。

②、参数列表中的占位符
占位符包含在命名空间std::placeholders中,使用前需要先使用命名空间。
而placeholders则定义在functional头文件中。

在参数列表中可以使用“_n“ n是常数,这样形式的东西来占位。
而数值n表示生成的可调用对象中参数的位置:_1为中间层函数的第一个参数,_2为中间层函数的第二个参数
在这里插入图片描述
③、绑定引用参数
使用函数ref
在这里插入图片描述

10.4 再探迭代器

迭代器的四大种类
在这里插入图片描述
这些迭代器都定义在iterator头文件里面

1、插入迭代器

在这里插入图片描述
通过一个对插入迭代器进行赋值,该迭代器将向容器插入元素
在这里插入图片描述
在这里插入图片描述
插入所指元素之前的位置

2、流输入迭代器(istream_iterator)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
用例1:利用迭代器指定范围构造vector
在这里插入图片描述

用例2:
在这里插入图片描述

3、流输出迭代器(ostream_iterator)

在这里插入图片描述
只有具有输出运算符(<<)的类型才能定义流输出迭代器

用例1:
在这里插入图片描述
用例2:
在这里插入图片描述

4、反向迭代器

反向迭代器就是在容器中从尾元素向首元素反向移动的迭代器。其递增和递减操作的含义会颠倒过来
在这里插入图片描述
下面带r版本的函数获取的才是反向迭代器

用例:逆序打印
在这里插入图片描述
①、反向迭代器转换为正向迭代器
输入一串以逗号为间隔的单词字符串:
在这里插入图片描述
在这里插入图片描述
结果会打印为TSAL,正好是LAST的逆序
这里需要使用反向迭代器的成员函数base来讲自己转换为普通迭代器
在这里插入图片描述
在这里插入图片描述
左闭合性

10.5 泛型算法结构

1、5类迭代器

泛型算法需要传入指定级别的迭代器才能实现功能
在这里插入图片描述
①、输入迭代器
在这里插入图片描述
只读、不写;单遍扫描,只能递增

②、输出迭代器
在这里插入图片描述
只写、不读;单遍扫描,只能递增

③、前向迭代器
在这里插入图片描述
可读可写;多遍扫描,只能递增

④、双向迭代器
在这里插入图片描述
可读可写;多遍扫描,可递增递减

⑤、随机访问迭代器
在这里插入图片描述
可读可写,多遍扫描,支持迭代器的全部运算

2、算法形参模式

在这里插入图片描述
①、接受单个目标迭代器算法
在这里插入图片描述
在这里插入图片描述
使用该模式的算法时需要保证目的地址有充足的空间

②、接受第二个输入序列的算法
在这里插入图片描述
在这里插入图片描述

3、算法命名规范

①、重载形式传递谓词
在这里插入图片描述
接受谓词的算法一般与普通算法重载

②、_if版本
在这里插入图片描述
接受一个谓词

③、_copy:区分拷贝和不拷贝
在这里插入图片描述
在这里插入图片描述
第一个版本的函数:当传入lambda表达式的i为奇数时,返回值 i%2 将会为1,也就是true。满足谓词的判断,所以将会触发remove,删除该元素。
第二个版本的函数:第一版将奇数元素删除完之后,剩下偶数元素拷贝到v2中

10.6 特定容器算法

链表list和forward_list有自己特有的成员函数版本算法。
因为链表不支持随机访问,如果使用通用版本会导致效率很低。所以库里面内置了成员函数版本的算法。
再遇到它们两个时,应该优先使用成员函数版本的算法,而不是通用算法。
在这里插入图片描述
在这里插入图片描述
这些特定版本的算法都会改变容器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值