C++程序设计:原理与实践(进阶篇)16.7 拷贝

16.7 拷贝


在16.2节中,我们认为f?ind()是“最简单的有用算法”。当然,这一点可以讨论。很多简单算法都是有用的——甚至其中有些编写起来有些过于简单了。当你可以使用其他人编写和调试好的代码时,为什么要费力编写新的代码?当谈及简单性和有效性时,copy()可以与f?ind()媲美。STL提供了三个版本的拷贝:

拷贝操作

copy(b,e,b2) 将[b:e)拷贝到[b2:b2+(e-b))

unique_copy(b,e,b2) 将[b:e)拷贝到[b2:b2+(e-b)),禁止拷贝相邻的相同元素

copy_if(b,e,b2,p) 将[b:e)拷贝到[b2:b2+(e-b)),但是仅拷贝满足谓词p的元素

 

16.7.1 基本拷贝算法

基本拷贝算法的定义如下:

 

 

给定一对迭代器,copy()将一个序列拷贝到另一个序列,目的序列用一个迭代器指明首元素。例如:

 

注意,copy()的输入序列类型可以与输出序列类型不同。这是STL算法的一种有用泛化:它们可用于各种序列,而无须对其实现做不必要的假设。我们要记得检查在输出序列中是否有足够的空间以保存拷贝来的元素。检查空间的大小是程序员的责任。STL算法的设计目标是最大的通用性和最佳的性能,它们(默认)没有做范围检查和其他代价昂贵的测试来保护用户。有时候,你可能希望它们做这些检查,但是当你想进行检查时,你可以像上面代码那样自己来完成。

16.7.2 流迭代器

你可能听到过短语“拷贝到输出”和“从输入拷贝”。这种思考方式对某种形式的I/O来说是很好、很有用的,我们确实可以用copy()做这些事情。

记住,一个序列是这样的东西:

它有开始和结尾;

我们可以用++移动到下一个元素;

我们可以用*得到当前元素的值。

我们可以很容易地用这种方式表示输入和输出流。例如:

 

你可以想象如何来实现它。标准库提供了一个ostream_iterator类型,就可以这样工作;ostream_iterator<T>是一个迭代器,你可以用它写入类型为T的值。

类似地,标准库提供了istream_iterator<T>类型用于读取类型为T的值:

 

通过ostream_iterator和istream_iterator,我们可以对自己的I/O使用copy()。例如,我们可以实现一个“快速和混乱的”字典,如下所示:

 

迭代器eos是表示“输入结束”的流迭代器。当一个istream到达输入结束(经常被表示为eof),它的istream_iterator将等于默认的istream_iterator(这里称为eos)。

注意,我们使用一对迭代器来初始化vector。作为一个容器的初始化器,一对迭代器(a, b)表示“将序列[a:b)读取到容器”。自然地,我们使用的一对迭代器是(ii,eos)——输入的开始与结束。这令我们不必使用>>和push_back()。我们强烈建议不要使用下面的替代方案。

 

那些试图猜测输入的最大规模的人,通常会发现他们低估了输入规模,从而遇到严重的问题——缓冲区溢出,无论对于他们自己还是他们的用户都是很严重的问题。这种溢出也是安全问题的一个来源。

试一试

首先,编译上面的程序令其正确运行,用一个小文件来测试它,例如一个包含几百个单词的文件。然后,尝试我们着重强调不推荐的猜测输入规模的版本,观察当输入缓冲区b溢出时发生什么。注意,最坏的情况是在特定例子中溢出没有导致任何错误,这样你就可能试图将它交付给用户。

在这个小程序中,我们读取单词然后进行排序。这在当时看来是一个明显的解决方案,但是我们为什么要将单词放在“错误的位置”,以至于随后我们不得不进行排序?更糟糕的是,我们发现一个单词在输入中出现几次,我们就会保存和打印它几次。

我们可以用unique_copy()代替copy()来解决后一个问题。unique_copy()不会重复拷贝相同的值。例如,如果使用普通的copy(),输入

the man bit the dog

程序会生成

 

如果我们使用unique_copy(),程序将会输出

 

这些换行是从哪里来的?带有分隔符的输出是很常见的,ostream_iterator的构造函数允许你(可选的)指定在每个值之后打印一个字符串:

 

很明显,对于供人类阅读的输出来说,换行分隔符是很常见的选择,但是也许我们喜欢使用空格作为分隔符呢?可以编写代码如下:

 

这将会生成输出

 

16.7.3 使用set保持顺序

有一个更容易的方式来得到上面那样的输出,使用set而不是vector:

 

当我们将值插入一个set时,重复的值被忽略掉。而且,set中的元素是按顺序保存的,因此不需要进行排序。通过使用正确的工具,大多数任务很容易完成。

16.7.4 copy_if

copy()算法进行无条件拷贝。unique_copy()算法禁止拷贝相同的相邻元素。第三种拷贝算法只拷贝令谓词为真的元素:

 

使用16.4节中的Larger_than函数对象,我们可以找到一个序列中大于6的所有元素,如下所示:

 

由于我犯的一个错误,这个算法错失进入1998 ISO标准的机会。这个错误现在已经被补救了,但是你仍然可以找到没有copy_if的C++实现。如果是这样,请使用本节中的定义。

时间: 2024-09-19 04:47:55

C++程序设计:原理与实践(进阶篇)16.7 拷贝的相关文章

c++-关于《C++程序设计原理与实践》第3章例子的一个问题

问题描述 关于<C++程序设计原理与实践>第3章例子的一个问题 本人菜鸟,现正在学习C++.<C++程序设计原理与实践>第3章有一个例子,代码如下: #include #include #include #include #include using namespace std; inline void keep_window_open(){ char ch; cin >> ch; } int main() //C++ Programs start by executi

源代码-C++程序设计原理与实践

问题描述 C++程序设计原理与实践 #include "std_lib_facilities.h" int main() { cout<<"Hello,world!n"; return 0; } 我下了源代码,放到那里才能猜VC98编译时不出错?最好详细点,带有图解 解决方案 ...大哥,都什么年代了还用98

《 C++程序设计:原理与实践(进阶篇.》导读

本节书摘来自华章出版社< C++程序设计:原理与实践(进阶篇)>一书中作者[美] 本贾尼·斯特劳斯特鲁普(Bjarne Stroustrup) 著 刘晓光 李忠伟 王刚 译     前 言 Programming: Principles and Practice Using C++, Second Edition 该死的鱼雷!全速前进. --Admiral Farragut 程序设计是这样一门艺术,它将问题求解方案描述成计算机可以执行的形式.程序设计中很多工作都花费在寻找求解方案以及对其求精上

100分求java语言程序设计进阶篇pdf

问题描述 求java语言程序设计进阶篇pdf 解决方案 解决方案二:同求啊!!!解决方案三:这个网上是没有的,我也在网上找过,我建议你去网上找java核心技术<上下卷>pdf这本书写的也是不错的,,这个网上有电子书的,,这两本书配合着java编程思想,相当的不错的解决方案四:真正的进阶是需要项目练习的,纸上得来终觉浅解决方案五:引用2楼xinzailiulei的回复: 这个网上是没有的,我也在网上找过,我建议你去网上找java核心技术<上下卷>pdf这本书写的也是不错的,,这个网上

学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践

原文 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践 感谢大家在上一篇 学一点Git--20分钟git快速上手 里的踊跃发言.这里再次分享干货, 简单介绍mysql双机,多机异地热备简单原理实战. 双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一 致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换到另一个. 2. 可以做负载均衡,可以将请求分摊到其中任何一台上

Node.js Stream - 进阶篇

上篇(基础篇)主要介绍了Stream的基本概念和用法,本篇将深入剖析背后工作原理,重点是如何实现流式数据处理和 back pressure 机制. 目录 本篇介绍 stream 是如何实现流式数据处理的. 数据生产和消耗的媒介 为什么使用流取数据 下面是一个读取文件内容的例子: const fs = require('fs') fs.readFile(file, function (err, body) { console.log(body) console.log(body.toString(

SQL Server调优系列进阶篇(如何索引调优)

原文:SQL Server调优系列进阶篇(如何索引调优) 前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本篇我们就开始分析这块内容,关于索引的基础知识就不打算深入分析了,网上一搜一片片的,本篇更侧重的是一些实战项内容展示,希望通过本篇文章各位看官能在真正的场景中找到合适的解决方法足以. 对于索引的使用,我希望的是遇到问题找到合适的解决方法就可以,

推荐系统——从原理到实践,还有福利赠送!

之前流水账似的介绍过一篇机器学习入门的文章,大致介绍了如何学习以及机器学习的入门方法并提供了一些博主自己整理的比较有用的资源.这篇就尽量以白话解释并介绍机器学习在推荐系统中的实践以及遇到的问题... 也许很多点在行家的眼里都是小菜一碟,但是对于刚刚接触机器学习来说,还有很多未知等待挑战. 所以读者可以把本篇当做是机器学习的玩具即可,如果文中有任何问题,还请不吝指教. 本篇将会以下面的步骤描述机器学习是如何在实践中应用的: 1 什么是推荐系统? 2 机器学习的作用 3 机器学习是如何使用的? 4

SQL Server调优系列进阶篇(如何维护数据库索引)

原文:SQL Server调优系列进阶篇(如何维护数据库索引) 前言 上一篇我们研究了如何利用索引在数据库里面调优,简要的介绍了索引的原理,更重要的分析了如何选择索引以及索引的利弊项,有兴趣的可以点击查看. 本篇延续上一篇的内容,继续分析索引这块,侧重索引项的日常维护以及一些注意事项等. 闲言少叙,进入本篇的主题. 技术准备 数据库版本为SQL Server2012,前几篇文章用的是SQL Server2008RT,内容区别不大,利用微软的以前的案例库(Northwind)进行分析,部分内容也会

《C++程序设计入门同步实践宝典 》可以下载了

<C++程序设计入门同步实践宝典>可以告一段落了.这是假期计划之外的事情,不小心又花了近二十天的时间,其他计划中的事情得一一落实了.将此版定为0.5版,以后还会有不小的改动. 下载地址:http://download.csdn.net/detail/sxhelijian/4482514 下载需要资源分5分,以对自己辛苦一番有所表示.常在CSDN泡的同学,也应该分享些你的原创挣点积分了.缺少积分的穷孩子,也可以给我留言,提供Email寄过去. 发个封皮: 有人提出上目录,好主意: 完工后写的前言