1、泛型算法:算法是因为其实现了一些经典算法的公共接口,如排序和搜索。泛型是因为他们可以作用于不同类型的元素和多种容器类型甚至是内置数组。故称泛型算法
2、基本上都定义在algorithm和numeric两个头文件中,这些算法遍历由两个迭代器指定的一个元素范围来进行操作,不对容器进行直接操作
3、所谓泛型算法就是作用于容器和元素上面的一些操作的合集,在实际情况中要善于使用
4、标准库基本上都是对一个范围内的容器进行操作,所以参数中总会有两个表示范围的迭代器
5、accumulate函数接受三个参数,前两个指出了需要求和的元素的范围,第三个参数是和的初值,第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型
6、用一个单一迭代器表示第二个序列的算法都假定第二个序列和第一个序列等长,如果实际中不等长,程序会出现错误
7、fill()算法的使用必须保证容器本身有足够的大小
8、拷贝(copy)算法接受三个迭代器,前两个表示一个输入范围,第三个表示目的序列的起始位置,此算法将输入范围中的元素拷贝到目标序列中,传递给copy的目标序列至少要包含与输入序列一样多的元素
9、replace算法接受4个参数:前两个是迭代器,表示输入序列,后两个一个是要搜索的值,另一个是新值,它将所有等于第一个值的元素替换为第二个值
10、sort算法接受两个迭代器,表示要排序的元素范围
11、unique算法重排输入序列,将相邻的重复项“消除”(覆盖),并返回一个指向不重复值范围末尾的迭代器
10、本阶段所学到的一些泛型算法:find()搜索,accmulate()求和,equal()相等判断,fill()、fill_n()赋值,back_insert()插入操作,copy()拷贝,sort()排序,unique()重排并消重复
11、很多算法在默认情况下都会使用元素类型的<或者==运算符完成比较,但标准库还为其定义了额外的版本,允许我们提供自己定义的操作代替默认的运算符,也就是说,向算法传递函数
12、谓词的定义:可调用的表达式,其返回结果是一个能用作条件的值。接受谓词参数的算法对输入序列中的元素调用谓词。
13、排序算法sort()-按大小重排,stable_sort()按大小排的同时,还按字典顺序,同大小不变顺序
14、我们希望对算法进行更多参数的操作,衍生出lambda表达式,一个lambda表达式表示一个可调用代码单元,它可以定义在函数的内部。
表达式的形式:f = 捕获列表->返回类型{函数体},参数列表为空时,()可省略。
如果未指定返回内容,则lambda返回void。
捕获列表是一个lambda所在函数中定义的局部变量的列表(通常为空),空捕获列表表明此lambda不使用它所在函数中的任何局部变量
15、lambda只有在捕获列表中捕获一个它所在函数的局部变量才能在函数体中使用该变量,lambda可以直接使用定义在函数之外的名字或者局部static变量
16、partition()返回的是最后一个使谓词为true的元素的后一个位置的迭代器
find_if()返回的是第一个使谓词返回非0值的元素,若不存在这样的元素,则返回尾迭代器
17、lambda的捕获方式:值捕获、引用捕获、隐式捕获,在[]中,
值捕获:被捕获的变量在lambda创建时拷贝
引用捕获:在lambda中使用引用捕获的变量时,实际上所使用的是引用对应的变量,也就可以在lambda函数体内修改该值。但是由于lambda捕获的是局部变量,必须保证函数结束后、lambda所调用的局部变量的地址仍然存在。
隐式捕获:让编译器根据lambda体中的代码推断我们需要使用哪些变量。&表示引用捕获,=表示值捕获。显示捕获与隐式捕获混合使用时,必须捕获方式不同。
18、尽量减少捕获的数据量,避免捕获可能导致的结果,避免引用、指针捕获。
本小节遇到的相关泛型算法:stable_sort()排序时相等长度元素维持原有顺序,partition()对容器进行划分,使得谓词为真的元素排在前面,返回最后一个使谓词为真的元素的后一个位置的迭代器,find_if()查找第一个具有特定大小的元素
19、值捕获想修改变量的话,可以在参数列表后加mutable进行修改。引用捕获也必须是非const的变量才可以进行修改。
20、若不明显指出返回类型,需要在参数列表之后使用尾置返回类型:->bool。
21、几种特殊的迭代器—实际上相当于一个泛型算法,接受一个容器作为参数,产生一个迭代器,将元素插入容器之中
插入迭代器:这些迭代器绑定到容器上,可以用来向容器插入元素
流迭代器:绑定到输入输出流上,用来遍历所有关联的IO流
反向迭代器:向后移动而不是向前移动,出了forward_list其他容器都有
移动迭代器:移动容器中的元素
22、插入器,接受一个容器作为参数,生成一个迭代器,可以向容器中添加元素。++it,it++,*it都不会产生任何效果,只能返回it(插入迭代器),it = t 在it指向的位置插入元素t。
23、插入迭代器分为三种:back_inserter()创建一个使用push_back的迭代器,front_inserter()创建一个push_front的迭代器,inserter()创建一个insert迭代器,接受两个参数。插入到指定迭代器之前。(前提是容器必须支持push_back()的操作
24、unique_copy():拷贝不重复元素,back_insert():插入迭代器(需包含iterator头文件)
25、io迭代器将他们对应的流当作特定类型的元素序列来处理。通过使用流迭代器,可以用泛型算法从流中对象读取数据以及写数据
26、反向迭代器,加上r,反向迭代器需要的是递减运算符,操作会从cbegin()反向处理string
27、rbegin()指向的是最后一个元素,rend()指向的是首元素之前的位置
28、通过调用反向迭代器的base()成员函数,可以将其转换为对应的普通迭代器
29、反向迭代器++是递减的运算符,向后移动,–是递增的运算符,向前移动
30、输入迭代器:可以读取序列中的元素。
输出迭代器,看作是输入迭代器的补集,可写。
前向迭代器:单向,支持输入输出。
双向迭代器:双向,支持读写,还支持递增递减运算符。
随机访问迭代器:基本支持所有功能。
31、sort()需要随机访问迭代器,所以不能用于list和forward_list.
31、对于list和forward_list应优先使用其成员函数版本的算法,皆返回void.
32、remove()删除元素,reverse()反转元素顺序,sort()排序,unique()删除相同元素
33、链表类型还定义了splice成员算法,其实链表数据结构所特有的,主要用于合并两个链表