6.6 练习
6-1 创建一个返回clock()(在<ctime>头文件中)当前值的发生器。创建一个list<clock_t>,并且通过该发生器用generate_n()填充它。在列表中删除任意副本,并且使用copy()把它打印到cout。
6-2 使用transform()和toupper()(在<cctype>头文件中),编写一个函数调用,将一个字符串全部转化成大写字母。
6-3 创建一个Sum函数对象模板,该函数对象模板在调用for_each()时,累加范围内所有的值。
6-4 编写一个回文构词法发生器,以一个单词作为命令行参数,并且产生所有可能的字母排列。
6-5 编写一个“句子回文构词法发生器”,以一个句子作为命令行参数,并且产生所有可能的句子中单词的排列。(不要落下某些单词,仅是将它们前后左右移动。)
6-6 用基类B和派生类D创建一个类层次结构关系。在B中放入一个virtual成员函数void f(),这样它将打印一个显示B中f()被调用的消息,且为D重新定义这个函数来打印一个不同的信息。创建一个vector<B*>,并且用B和D的对象填充它。使用for_each()来为vector中的每个对象调用f()。
6-7 修改FunctionObjects.cpp,以便用float代替int。
6-8 修改FunctionObjects.cpp,模板化测试的主体,这样就能选择要测试的类型。(必须把main()的大部分放入到一个单独的模板函数中。)
6-9 编写一个程序,以一个整数作为命令行参数,并找出它的所有因数。
6-10 编写一个程序,以一个文本文件的名称作为命令行参数。打开这个文件并且每次读入一个单词(提示:使用>>)。将每个词存储到一个vector<string>。将所有的词转化成小写,存储它们,删除全部的副本并打印结果。
6-11 编写一个程序,使用set_intersection()找出两个输入文件中共有的所有单词。修改程序,使用set symmetric_difference()来显示两个输入文件中非共有的单词。
6-12 创建一个程序,在命令行给定一个整数,创建一个向上直到包括命令行数值在内的所有整数的阶乘的“阶乘表”。为了完成这个工作,编写一个发生器来填充vector<int>,然后与标准函数对象一起使用partial_sum()。
6-13 修改CalcInventory.cpp,使它能找到所有数量小于某个总数的对象。提供这个总数作为命令行参数,并使用copy if()和bind2nd()来创建小于目标值的数值的集合。
6-14 使用UrandGen()产生100个数。(数的大小没有关系。)找到范围中模23的同余数(意思是当被23除时有相同的余数)。读者手工挑选一个随机数,确定这个数是否在该范围中,这是通过用这个数除以列表中的每一个数并检查结果是否是1来实现的,用手选的这个值替代使用find()进行查找。
6-15 用在弧度制中表示角度的数填充vector<double>。使用函数对象组成,产生vector中的所有元素的正弦(见<cmath>头文件)。
6-16 测试读者所使用的计算机的速度。调用srand(time(0)),然后建一个随机数的数组。再次调用srand(time(0)),并在第2个数组中生成相同个数的随机数。用equal()来看两个数组是否相同。(如果你的计算机足够快的话,两次调用time(0)将返回相同的值。)如果两个数组内容不相同,对它们进行排序,并使用mismatch()来看看它们到底哪里不相同。如果相同,增加数组的长度并再次测试。
6-17 创建一个STL风格的算法transform_if(),它遵循transform()的第1种形式,即仅在满足一元判定函数的对象上执行变换。将不满足判定函数的对象从结果中忽略掉。需要返回一个新的“末端”迭代器。
6-18 创建一个STL风格的for_each()的重载形式算法,它遵循transform()的第2种形式。它用两个输入范围,这样就可以将第2个输入范围的对象传递给一个二元函数,对第1个范围中的每个对象应用这个函数。
6-19 创建一个由vector<vector<T>>制造的Matrix类模板。用提供给它的一个友元ostream&operator<<(ostream&,const Matrix&)来显示矩阵。在可能的地方用STL函数对象创建以下二元运算:operator+(const Matrix&,const Matrix&)执行矩阵加法,operator(const Matrix&,const vector<int>&)用一个vector乘一个矩阵,operator(const Matrix&,const Matrix&)执行矩阵乘法。(如果忘记了它们的运算规则,可能需要查找一下矩阵运算的数学含义。)使用int和float测试建立的Matrix类模板。
6-20 使用以下的字符
生成一个密码本,以命令行给定的输入文件作为单词字典文件。不考虑排除非字母的字符,也不考虑单词在字典文件中的语境意义等情况。使每一种字符串的排列映射为一个单词,例如:
等等。
确认在密码本中不存在副本(相同)的密码或单词。使用lexicographical_compare()在密码上执行排序。用密码本把字典文件译成密码。再对编码的字典文件进行解码,并确认得到的解码文件是否与原文件有相同的内容。
6-21 用下面的名字
找到一个为这些人安排婚礼照片的所有可能的方法。
6-22 在区分照片后,每对新娘和新郎都希望所有其他照片上的人们作为来宾一起参加他们的婚礼。例如,如果新娘和新郎(Jon Brittle和Jane Brittle)相邻,找出为照片上的这对新人安排来宾的所有的可能方法。
6-23 一家旅行社想要找出游客们从一个大陆的一端旅行到另一端(贯穿这个大陆)所花费的平均天数。问题是在调查中,一些游客不采用直接的路线,所用的时间往往要比需要的多(这样的例外数据点称为“局外点”)。使用下面的发生器,在一个vector上产生旅行天数。使用remove_if()删除vector中的所有的局外点。用vector中数据的平均值找出一般要花多长时间才能够完成旅行。
6-24 在对一个已排序的序列范围进行查找时,确定采用binary_search()(二分查找)要比find()(顺序查找)有多快。
6-25 某军队想在供选择的服役报名名单中征募新兵。他们已经决定征募那些在1997年报名注册应征的人们,按照出生日期,从年龄最大的开始依次征募直至最年轻的。在vector中产生任意数量的人(提供数据成员,如age和yearEnrolled)。划分vector,使那些在1997年登记注册的应征新兵在名单的开始位置,按照从最年轻的到年龄最大的顺序排序,名单中其余的部分按年龄从大到小排序。
6-26 用人口、(海拔)高度和天气等数据成员建一个名为Town的class。天气由一个enum用枚举常量表{RAINY, SNOWY, CLOUDY, CLEAR}建立。建一个产生Town对象的类。生成城镇的名称(采用读者自己起的有意义或者与地域无关的名称都行)或是从互联网上相关网站得来。保证全部的城镇名称是小写字母,并且没有重复。为了简便起见,我们建议保持城镇名称为一个词。为人口、海拔高度和天气字段,创建一个发生器,随机产生天气情况,在范围100,1 000000)内的人口及[0,8000)英尺[[1]内的海拔。用Town对象填充vector。把vector重新写入一个名为Towns.txt的新文件。
6-27 有一个生育高峰,导致了每个城镇人口按10%的速度增长。使用transform()更新这些城镇数据,并将数据重新写回文件中。
6-28 用最高和最低人口来查找这些城镇。这个练习对Town类实施operator<操作。并尝试实现一个函数,该函数当第1个参数小于第2个参数时返回true。将它作为所使用算法的判定函数。
6-29 找出所有海拔在2500~3500英尺间的城镇。根据需要对Town类执行相关运算。
6-30 现在需要在某个海拔高度的地方建一个飞机场,而场地位置不是问题。整理现有的城镇名单使其没有副本(副本意味着:在相同的100英尺范围中不能有两个海拔。例如这样的类包括[100,199)、[200,199)等等)。使用<functional>中的函数对象,至少用两种不同的方式将名单按升序排列。以降序完成相同的工作。根据需要对Town实现相关运算。
6-31 在基于栈的数组中产生一组任意数目的随机数。使用max_element()找到数组中最大的数。将它与数组末尾的数进行交换。找到次最大的数并且放在先前的数之前。持续这样做直到所有的元素都被移动过。当算法结束时,就得到一个排好序的数组。(这就是“选择排序”。)
6-32 编写一个程序,从一个文件中提取电话号码(同时也包括名字以及其他需要的信息),并且将以222开始的电话号码改变为以863开始。同时要保存旧的号码。文件形式如下所示:
等等。
6-33 编写一个程序,给定一个姓氏,找出每个有这个姓氏的人以及他或她的电话号码。使用处理序列范围的算法(例如lower_bound、upper_bound、equal_range等等)。以姓氏作为主关键字,名字作为次关键字进行排序。假定从形式如下的文件中读入姓名及电话号码。(对它们进行排序,先按姓氏排好序,在同姓氏的人们中再按名字排好序。)
6-34 给定一个包含类似下面数据的文件,将所有州的首字母省略词提取出来并将其放入一个单独的文件中。(注意,不能为某个数据类型决定该数据所占的行数,数据所占的行数是随机的。)
等等。
当完成时,会得到一个含所有州的首字母省略词组成的文件,如下所示:
6-35 创建一个Employee类,该类含有两个数据成员:hours和hourlyPay。Employee还含有一个返回雇员薪水的函数calcSalary()。对任意数量的雇员产生随机的小时薪水及工作小时数。用一个vector<Employee*>来存放这些数据。查看一下公司将为这段付薪时期花多少钱。
6-36 再次相互比较sort()、partial_sort()和nth_element()函数,请查明如果都需要使用它们,那么使用其中的那一个进行弱排序可以更节省时间。
[1]1英尺=0.305m。