C++ Primer 第十章 10.5~10.6 泛型算法结构 练习和总结

10.5 泛型算法结构

泛型算法是在迭代器上进行操作的,所以每一个算法都需要迭代器提供它所需的操作,按照可读,可写,递增,递减等迭代器操作,算法对迭代器的操作要求可以分为5个类别。

迭代器名字 支持的操作
输入迭代器 只读、不写、单遍扫描、只能递增
输出迭代器 只写不读、单遍扫描,只能递增
前向迭代器 可读可写;多遍扫描;只能递增
双向迭代器 可读可写;多遍扫描;可递增递减
随机访问迭代器 可读可写;多遍扫描;支持全部迭代器运算

这里的支持全部迭代器运算就是3.4节迭代器所支持的操作里面的所有操作。

每个算法都会迭代器有着**最低的要求,**如果迭代器不满足最低要求则编译报错。高级别的迭代器支持低级别迭代器的所有操作

迭代器类型 必须支持的操作 迭代器举例
输入迭代器 iter1==iter2;iter1!=iter2;++iter;++iter;*iter(只能出现在赋值运算符右侧),iter->member istream_iterator
输出迭代器 iter++;++iter;*iter(只能用于赋值运算符左侧) ostream_iterator
前向迭代器 上述两个的所有操作都要有 forward_list的迭代器
双向迭代器 输入输出迭代器的操作都需要;–iter;iter– 除了forward_list之外的所有标准库容器都必须满足双向迭代器的要求
随机访问迭代器 支持双向迭代器的所有操作;iter1<iter2;<=;>;>=;iter+n,iter+=n;-n,-=n;iter1-iter2;iter[n] string,array,deque,vector的迭代器要求为此类迭代器,数组的指针也是此类迭代器

目前的疑问,多遍扫描和单遍扫描分别是什么意思

这里的意思应该是能够遍历多次,像输入输出迭代器,因为流的状态会改变,所以就算我保存了迭代器,迭代器在赋值或者其他操作中,会导致之前的迭代器失效。所以输入输出迭代器只支持单次扫描。但是前向迭代器不会这样,所以前向迭代器可以保留之前的迭代器多次遍历。

练习

10.38

已经在上面的表中列出。

10.39

如上表所属,list的迭代器属于双向迭代器,vector的迭代器属于随机访问迭代器

10.40

首先分析,copy不需要读取元素,也不需要单遍扫描,所以copy第一二个参数,要求输入迭代器,第三参数要求输出迭代器。

reverse()需要替换元素,所以需要可读写。我觉得单向迭代器应该是可以的,不过需要计数器和多次遍历。
不过C++标准规定的是双向迭代器。

unique()需要写入元素,消除重复元素,查看编译得知是需要前向迭代器。

= =感觉很难推测。。

10.5.2 算法形参模式

大部分的函数都支持以下的四种形式
在这里插入图片描述
他们都接受一个输入范围(beg,end),然后后面的参数各有不同。

dest通常表示目标迭代器

如果算法只接受beg2,则序列2从begin2开始大小至少和(beg,end)一样大。

如果dest的目标位置是一个容器的迭代器,那么要求这个容器的空间是足够的,否则会造成未定义的结果。

10.5.3 算法命名规范

很多算法支持传入谓词,但是支持的方法各有不同。
比如unique,是以重载的形式支持。

但是find则是通过在find_if()来支持。

初次之外,还有_copy的算法,这些方法不改变序列本身,而是将改变后的序列传入目标位置。

练习

10.41

1.将输入范围内的old_val,替换为new_val
2.将输入范围内,满足pred表达式的,替换为new_val
3.将输入范围类的old_val,替换为new_val,并传入dest指向的目标位置
4.将输入范围内,满足pred表达式的,替换为new_val,并传入dest指向的目标位置

10.6 特定容器算法

有些容器可以使用泛型算法,但是使用泛型算法的效率很低,为了解决这个问题,有些容器对算法有自己的容器。

比如list和forward_list。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个splice其实就是移动元素。

不同于泛型算法,这些定于在类中的算法,通常会改变容器的低层大小,这很容易理解,因为算法不是通用的,所以可以为了提高效率做一些优化。

如果一个算法有通用版本和容器自带版本,那么选择容器自带的版本

练习

10.42
list<string> slst = { "a","c","a","e123","1ca","aaa","aaa","z123","q","casd123","asdas" };
	slst.sort();
	slst.unique();
	std::ostream_iterator<string> oiter(cout, " ");
	std::copy(slst.begin(), slst.end(), oiter);
发布了54 篇原创文章 · 获赞 6 · 访问量 3316

猜你喜欢

转载自blog.csdn.net/zengqi12138/article/details/104354821