编写一个能模拟简单猜扑克牌大小游戏的应用程序。该游戏的名称为Hi-Low,其玩法
和规则如下: 1玩法
①洗牌:每盘游戏开始之前,使扑克牌的排列顺序充分随机。
②发牌:每局开始时,从未使用的扑克牌集合中顺序发给玩家5张扑克牌(明牌)。 ③猜点:从未使用的扑克牌集合中按顺序取出一张扑克牌(即庄家的暗牌),要求
玩家将手中的第一张扑克牌和这张庄家的暗牌进行比较,确定哪张牌大?
④积分:玩家确定回答后,翻开被猜的扑克牌(暗牌变成明牌),同时根据玩家回
答的正确与否显示相应的提示,并为玩家的游戏成绩积分。然后将这两张 已经比较过的牌回收到已经使用过的扑克牌集合中,玩家手中的下一张扑 克牌成为新的一张扑克牌。
⑤对玩家手中剩余的扑克牌顺序重复第③和④步操作,直至玩家手中不再有剩余的
扑克牌时,一局游戏结束。
⑥如果未使用的扑克牌集合中的扑克牌数目多余10张,则从第②步自动开始进行
本盘游戏的下一局。
⑦询问玩家是否继续进行下一盘游戏,如果继续,则从第①步开始进行新的一盘游
戏。
2规则 ①积分规则: · 猜中1次,积1分;猜错1次,不积分。 · 1局中连续猜中3次,除正常积分外奖励1分;连续猜错3次,罚1分。 · 1局全部猜中,除正常积分外奖励3分;1局全部猜错,罚3分。 · 玩家的最低积分为0,即不出现负分。
②牌面大小比较规则:每张扑克牌的牌面由花色(梅花Club、方块Diamond、红
心Heart和黑桃Spade)和牌点(A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K)组成。 确定两张扑克牌牌面大小的规则有两条:
· 如果两张牌面的牌点不同,则牌面大小仅与牌点有关,而与牌面的花色无关。 牌点的大小顺序为:2 <3 <4 <5<6<7<8<9<10 Hi-Low。 *4要求编写编程文档,文档内容包括:   ① 绘制各个组成类的类图与类图之间的静态关系图     ② 各个组成类的类定义描述     ③ 主要功能函数的算法描述   ④ main()函数的流程图 提示: 1 分析各种扑克牌游戏,可以归纳出如下几条规律: ①一副扑克牌,即扑克牌的全集是有54张具有不同牌面的扑克牌组成的。 ②任何一种扑克牌游戏都需要使用由n张扑克牌组成的集合,该集合可以是一副 扑克牌的全集,也可以是一副扑克牌的子集,甚至可以是多副扑克牌的并集。例 如Hi-Low游戏需要使用一副扑克牌中除大小王牌Trump以外的52张牌组成的 子集。 ③任何一种扑克牌游戏都会根据自己的玩法和规则,确定一种若干步特定操作构成 的游戏程式。 ④每一种扑克牌游戏都会根据积分规则确定一个相对的积分计算器,依据游戏 结果为玩家计算积分。 2 根据上述分析,建议进行如下的对象类分解: ① 将扑克牌对象设计为一个类Card,用于定义标识每一张特定扑克牌的牌面(花 色和牌点)和显示操作。为此该类可以用如下属性和操作描述: 属性: · 牌面属性face作为每张扑克牌唯一标识,确定了每张牌的花色和牌点。该属 性可以声明为一个包含了两个元素的整型数组。 其中face[0] 用于存放牌面的牌点: 1-13对应的牌点为2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A; face[1]用于存放牌面的花色: 1–4 对应的花色为Club, Diamond, Heart, Spade。 为了使该属性不能被随意修改,因此该属性应该声明为私有成员。 操作:  · 构造函数:无参数,便于创建对象数组。 · 初始化操作Init:依据传入参数值,为牌点face[0]和花色face[1]赋值。该操 作应向外提供服务。 · 获取牌点操作Value:无须参数,返回face[0]的当前值。该操作应向外提供 服务。 · 获取花色操作Face:无须参数,返回face[1]的当前值。该操作应向外提供服 务。 · 显示牌面操作Show:依据牌面属性face的当前值,显示相应的字符串。例 如,当一张牌的牌面属性face[0]=12;face[1]=4,则显示的字符串就可以是 Spade– Q。该操作应向外提供服务。 注意,如果在图形界面的应用程序中该操作就可以显示相应的牌面图形。 ② 考虑到结构的合理性,可以将计算游戏积分所需要属性和操作封装在一个类中。 该类可以命名为Counter,它所包含的属性和操作如下: 属性: · 积分属性score:用于记录游戏的积分值。为了能记录足够大的积分值,该 属性应声明为长整型long。 · 连续标志属性sequence:用于存放玩家当前猜点操作的连续状态: 连续猜中时,sequence> 0(连续猜中的次数); 连续猜错时,sequence< 0(连续猜错的次数); 即未连续猜中,也未连续猜错时,sequence = 0。 操作: · 构造函数:将积分属性score和连续标志属性sequence初始设置为0。 · 累计积分操作accumulate:根据玩家当前猜点操作的结果(布尔类型值,  通过实参传递该操作)修改玩家当前的连续猜中状态sequence,并根据猜 点操作的结果和连续猜中状态,按积分规则玩家累计积分。该操作应向外提 供服务。 · 显示积分操作Show:显示游戏积分值。该操作应向外提供服务。 · 清除连续标志操作ClearSequece:在游戏新的一盘开始前,设置Sequece 为0。 ③ 根据扑克牌游戏的玩法和规则,将扑克牌游戏设计成一个类。在类的定义中描述 游戏该游戏所需要使用的扑克牌集合和所需要的辅助属性,以及满足游戏玩法和 规则的各种操作。本题中的扑克牌游戏类可以直观地命名为HiLow,它应该包 括如下属性和操作: 属性: · 扑克牌集合属性deck:存放HiLow游戏所要使用的52张扑克牌(不需要 大小王牌)。该属性是一个Card类型的数组。 · 已用牌索引属性used:指示deck中游戏已经使用过的扑克牌的索引。每盘 游戏开始时,该属性应被初始化为0(deck的第一个元素的下标值);以后 每次从deck取一张牌(为玩家每发一张牌或取一张被猜的牌)后,该属性 值增1。该属性的值域为0 ≤ used ≥ 51。 · 玩家牌索引属性index:指示当前玩家手中正在进行猜点操作的牌在deck 中 的索引。每局游戏开始时,该属性值 = used;以后每次猜点操作完成后, 该属性值增1。该属性的值域为0 ≤ index ≥ 51。 · 积分计算器属性counter:该属性是一个Counter类对象,用于为游戏提供 积分管理。 操作: · 构造函数:完成HiLow游戏对象的创建。在此创建操作中要完成各个属性必 要的初始化,其中对deck中每个元素的初始化是调用 Card类的Init操作 逐个完成的。 · 洗牌操作Shuffle:该操作应向外提供服务,用于deck中的元素(扑克牌) 进行随机排列。模拟真实的洗牌操作可以通过52次将deck中的两个由随机 下标索引的元素进行交换操作来实现。产生随机下标可以调用库函数rand 来完成,52次交换操作就需要调用rand 52次。值得注意的是,在第一次调 用rand之前应该调用另一个库函数srand为随机数发生器播种,即初始随 机数,使得每次洗牌所需要的52个随机数序列都不一样。获得这个初始随 机数的最简单方法就是调用库函数time获取当前的时间值作为初始随机数。 因此调用srand创建随机数发生器的表达式可以写为: srand((unsigned)time(NULL)); 库函数rand和srand的原型声明在系统头文件stdlib.h中;    库函数time的原型声明在系统头文件time.h中。    另外,库函数rand所产生随机数的值域范围是0至整型数最大值,可以通 过对函数的返回值模52运算(rand() % 52),获得值域范围为0至51的随 机下标值。 调用洗牌操作意味着新的一盘游戏的开始,因此,在上述随机排列操作完成 后,需要将used和index设置为0,还需要调用积分计算器属性counter 的成员函数ClearSequece清除积分连续标志(sequence = 0)。 · 发牌操作Deal:该操作应向外提供服务,用于每次为玩家发5张扑克牌。完 成这一操作只需调整used和index的值,而无须发生扑克牌的获取操作。 · 显示玩家手中牌操作PlayerShow:该操作应向外提供服务,用于显示当前 玩家手中所有可以用猜牌操作的扑克牌的牌面信息。这些牌的索引范围是: index至index + 4。 · 比较操作Check:该操作应向外提供服务,用于一次比较玩家明牌和庄 家暗牌大小的操作,并返回比较结果(布尔)标志(玩家牌大为ture,否则 为false)。被猜的两张牌的索引可以通过index和used获得(注意访问后, 需要对index和used属性值分别增1)。 · 显示猜牌结果操作ResultShow:该操作应向外提供服务,用于在比较操作 Check被调用后,显示用于比较大小的玩家牌和庄家牌的牌面信息,即根据 比较结果(作为实参传递给操作)显示相应的提示信息。注意,被显示的两 张牌的索引是index - 1至used - 1。 · 积分操作accumulate:该操作应向外提供服务,该操作是根据玩家的本次 猜牌结果(布尔)标志(猜中为true,否则为false),调用积分计算器counter 的成员函数accumulate完成玩家的游戏积分计算和管理。玩家的本次猜牌 结果应通过布尔类型实参传递给操作的。 · 判断一局结束操作IsGameOver:该操作应向外提供服务,用于提供游戏的 局结束(布尔)标志(结束为ture,未结束为false)。如何判断一局是否结 束,可以通过分析index值的变化规律发现。注意,如果一局结束,还需要 调用积分计算器counter的成员函数ClearSequece清除积分连续标志 (sequence = 0)。 · 判断一盘结束操作IsSetOver:该操作应向外提供服务,用于提供游戏的盘 结束(布尔)标志(结束为ture,未结束为false)。如何判断一盘是否结束, 可以通过分析used值的变化规律发现。 · 显示游戏积分ScoreShow:该操作应向外提供服务,用于显示玩家的当前 戏积分。此操作是调用积分计算器属性counter的成员函数Show实现的。 3 在主函数main()中创建HiLow游游戏对象,使用该对象提供各项操作功能,实现 游戏的玩法所要求的操作和控制。注意,在游戏的各步操作中应提供恰当的提示信 息,以便提供友好的操作界面。 难度等级:**** 题目2 定义一个用于链表的学生结点类Student,它的定义如下所示: class Student {  Long id;    // 学生学号  stringname;   // 学生姓名  int age;    // 学生年龄  string sex;   // 学生性别  string specialty;  // 所学专业 Student* next;  // 指向链表中下一个Student结点类对象的指针 static Long numTotal; // 学生总数,该属性在所有的学生对象创建前应被初始化 // 为学号基数(第一个学生的学号),每个新生的学号=该 // 属性当前值,然后该属性值增1。 public:  Student();   // id=numTotal,name=””,age=6,sex=””,specialty=””, // next=0,numTotal ++ Student(string n, int a, string s, string spec); // id=numTotal, age=a, name=n,sex=s, // specialty=spec,next=0,numTotal ++ ~Student();     int Compare(long id); // 将学生对象的学号与指定的学号id进行比较, // 如果Student::id // 出格式可以按如下形式: // 学号:XXXXXXXXXX // 姓名:XXXXX 年龄:XX  性别:XX // 专业:XXXXXXXXXX }; 要求: 1 在类定义体外实现Student类各个成员函数的定义。 2 定义一个单链表结构的学生信息集合类StudentSet,该集合可以按学号顺序插入需 要保存所有的学生信息(每个学生的信息保存在Student类对象),可以查询指定 的学生信息,可以删除指定的学生信息,可以显示集合中保存的所有学生信息。为 此,学生信息集合类StudentSet必须具有必要的属性和操作: ① 集合链表头指针head,用于指向链表的头结点,因此它的类型应该是Student*。   该指针在StudentSet对象创建时必须被初始化为空(head = 0)。该指针只在 类对象的操作中被访问,所以它是private数据成员,并且不需要提供在类对象 外访问head的接口。 ② 集合构造函数StudentSet,链表结构集合创建时应是一个空链表。 ③ 集合析构函数~StudentSet,链表结构集合析构(撤消)时,如果链表不为空, 则需要将链表中的各个结点逐一撤消。 ④ 集合判空操作IsEmpty,该成员函数用于判断集合(即链表)是否为空,并将 判断结果以一个布尔(bool)类型值作为标志返回。 ⑤ 学生信息结点插入操作Insert,该成员函数的功能是将一个动态创建的Student 类型的新生对象作为结点按学号顺序插入链表。创建新生对象所需要的各项属性 (姓名、年龄、性别、专业)应通过参数的形式传递给函数的操作。注意,新生 必须是在堆中动态创建的对象,而不能是在堆栈中创建的局部对象。 ⑥ 查询指定学生信息操作Contain,该成员函数的功能是查询集合中是否存在指定 学号的学生。被查询学生的学号通过参数的形式传递给函数的操作,如果被查询 学生存在,则返回链表中该学生的地址,否则返回空地址。 ⑦ 删除指定学生信息操作Delete,该成员函数的功能是:如果指定学号的学生在 链表中,则将该学生从集合中删除;否则结束操作。被删除学生的学号通过参数 的形式传递给函数的操作, ⑧ 显示集合中全部学生信息操作ShowAll,该成员函数的功能是:如果集合不为 空,则顺序输出集合中所有学生的信息。 3 在主函数main()中完成如下操作: ① 建立一个学生信息空集合(StudentSet类对象)。 ② 显示集合中的全部学生记录信息。 ③ 编写一段代码实现通过键盘能逐个输入任意个学生的各项信息(姓名、年龄、性 别和专业),并以这些信息为参数创建学生信息记录(Student类对象)对象,  并将它们顺序插入链表中,直至人为结束输入(例如,通过键盘输入Ctrl+Z)。 ④ 再次显示链表中的全部学生记录信息。 ⑤ 编写一段代码能够实现以下所描述的任意次查询操作: · 通过键盘输入学号; · 根据此学号在集合中查找有无学号匹配的学生记录; · 如果存在,则显示该学生的信息; · 询问用户是否从集合中删除该学生记录; · 若删除,则将学生记录从集合中删除,然后显示集合中的全部学生记录信息; · 如果集合中没有学号匹配的学生记录,否则显示相应的提示信息; · 直至集合为空或人为结束查询操作(例如,通过键盘输入Ctrl+Z)。 *4要求编写编程文档,文档内容包括: ① 绘制Student和StudentSet类图和类图之间的静态关系图    ② Student和StudentSet类定义描述  ③ main()函数的流程图 提示: 1由于链表集合类StudentSet中结点是Student类型,为了操作方便和提高访问速 度,应该在Student类中将StudentSet声明为友元。为此,需要对Student的定 义做相应的修改。 2 学号的构成规则可以确定为年级+5位长度的注册顺序号,例如,2005年级的学生 学号基数 = 200500001。 3 从键盘接收字符串建议调用输入流的成员函数getline,调用方法例如:  … string id; getline(cin,id);  … 即可从键盘获取字符串。如果在键盘上键入复合键Ctrl+Z后回车结束一次输入操作, 则会产生输入空串的结果,即id = “”。 难度等级:*** 题目3 数值的进制的表示总是用以进制n为模的余数所对应的数值码组成的,例如,2进制数 的数值码为0,1;3进制数的数值码为0,1,2;…而10进制数的数值码为0,1,2, 3,4,5,6,7,8,9等。 根据上述概念,定义一个能够表示任意进制整数的自定义整数类RandomInt,该类能 表示2至16进制之间的任意进制整数,也就是说,能按照当前进制整数的运算规则和 表示规则对该整数类对象施加算术四则运算和进行输入输出操作。 要求: 1. 正确、合理地设计和实现能满足题意要求的任意进制整数类RandomInt。为此要求 该类应包括以下属性和操作: 属性: ① 进制属性mod:该属性为int类型,取值范围为[2,16]。该属性用于存放RandomInt 类对象的当前进制值,例如,mod= 3,表示RandomInt类对象表示的是三进制 整数。该属性是判定输入数值码合法性和输出数值码转换的依据。 ② 数值属性value:该属性为int类型,取值范围为系统确定的整型数取值范围。该 属性用于存放RandomInt类对象的当前值,注意该数值总是以十进制表示的, 这样将有利于利用系统已经确定的十进制整数的操作规则。而表示该数值的数值 码取决于进制属性mod,例如,RandomInt类对象的value= 45,mod= 3, 则表示该整数对象的数值码就应该是1200;如果RandomInt类对象的mod= 8, 则表示value= 45的数值码就应该是55。 操作:   ① 构造函数应能适应两种情况:   ·不传递参数的构造函数:该构造函数将进制属性mod设定为缺省进制值10, 数值属性value 设定0,也就是构造一个表示十进制的RandomInt类对象,其 初值等于0。 ·传递指定进制值和数值的构造函数:该构造函数通过参数将所创建RandomInt 类对象的进制属性mod设定为指定进制,将数值属性value设定为指定值。 ·拷贝构造函数:由于属性value是一个需要动态分配存储空间的指针,因此必 须为RandomInt类对象自定义拷贝构造函数。注意根据进制值的取值范围检 查参数所传递的进制值的合法性。 ② 算术四则运算操作:能使用算术四则运算符完成两个RandomInt整数的算术四 则运算操作并返回计算结果(RandomInt整数)。这类操作必须在两个同进制的 RandomInt整数对象之间进行,因此在运算操作之前,必须判别参与运算的两个 RandomInt整数对象的进制是否相同;如果不相同,则先进行进制的转换规一, 然后在进行相应的四则运算操作。进制的转换规一规则指定为“向左规一”,即转 换右操作数的进制与左操作数的进制一致。 注意,重载的四则运算符应该能满足参与运算的两个操作数中可以有一个是系统 预定义int类型常数(10进制),而运算符的返回值必须是一个RandomInt类对 象。 ③输入、输出操作:能对标准输入流cin使用输入运算符>>和对标准输出流cout 使用输入运算符<<对RandomInt类对象所表示的整数进行输入和输出操作。 在这类操作中应注意以下几点: ·输入操作是将从标准输入流中获得的一个由数值码组成的字符串,并按照目标 (RandomInt)对象的进制属性mod检查字符串中数值码的合法性,将字符 串中连续的合法子串转换为相应的十进制数值,赋予RandomInt类对象的数 值属性value。例如,从标准输入流获得的字符串为”-12100420”, RandomInt 类对象的进制属性mod= 3,则合法子串为”-12100”,转换后的十进制值是 -144,即RandomInt类对象的数值属性value被赋值为 -144。 ·输出操作是将源(RandomInt)对象的value中保存的十进制数值按照进制属 性mod中存放的进制值转换为相应进制的数值码字符串,并该字符串添加到 标准输出流中输出显示。例如,被输出的RandomInt类对象的mod= 3,value= 145,则转换输出的数值码字符串是”12101”。  注意,符号应该单独处理。 ④ 改变进制操作:将RandomInt对象的进制属性mod的值修改为由参数指定的新 进制值。注意根据进制值的取值范围检查参数所传递的进制值的合法性。 ⑤ 类型转换操作:将RandomInt对象所表示任意进制整数转换为系统预定义整数 类型int值,并返回。 2. 定义一个类外全程函数 void Solve(RandomInt&a, RandomInt& x, RandomInt& b); 用于求解关于x的方程ax = b。 3. 在主函数main() 中对任意进制整数类型RandomInt的功能进行如下验证: ①创建3种不常使用的进制(例如,3、5、7进制)RandomInt整数对象,每种进 制各创建3个对象。注意,要求每种进制的3个对象中2个使用有参数的构造函 数创建,1个使用无参数的构造函数创建。 ② 通过标准输入流分别为使用无参数构造函数创建的3种进制的RandomInt 整数 对象输入相应的数值。 ③ 通过标准输出流顺序输出显示所有已经创建的RandomInt整数对象。 ④ 使用所创建的RandomInt整数对象,分别验证三种模值的RandomInt对象的分 配律:   a * (b + c) = a * b + a * c   共验证4次,前3次操作中验证分配率表示式中的a、b、c使用3个相同进制的 RandomInt整数对象,最后一次操作中验证分配率表示式中的a、b、c使用3 个不同进制的RandomInt整数对象。每次验证都应显示恰当的提示和验证结果。 例如: a * (b + c) = XXXX a * b + a * c = XXXX X进制的四则运算分配率a * (b + c) = a * b + a * c成立 注意,上述输出中X进制。。。的X是用于验证分配率的RandomInt整数对象的 进制值;XXXX分别表示分配率表示左边和右边的计算结果。 ⑤ 调用类外函数Solve求解关于x的方程ax = b。共调用4次,前3次调用时方程 中的a、b使用两个相同进制的RandomInt整数对象,最后一次调用时方程中的 a、b使用两个不同进制的RandomInt对象。每次调用都应显示恰当的提示和求 解结果。 4.要求编写编程文档,文档内容包括:(选作)  ① RandomInt类图 ② RandomInt类定义描述 ③ 重要类成员函数和全程类外函数Solve的实现算法描述   ④ main()函数的流程图 提示: 1.n位任意m进制整数Nn-1Nn-2…N2N1N0的值可以表示为:   Nn-1×mn-1+Nn-2×mn-2+ … +N2×m2+N1×m1+N0×m0 其中组成m进制整数每一位数码满足m-1 ≤ Ni ≥ 0。 2. 数字的进制只是数值的计数和表示方法,而不会影响数值的大小,因此任意进制数字 之间的算术四则运算既可以任意的m进制值,以“逢m进1”的规则直接按位进行; 也可以将任意的m进制数字的值,按一种指定进制(10进制)进行运算,然后再将 运算结果按确定的m进制表示。两种实现方法的结果是完全一致的。 3. 为了提高代码的重用率,应该将RandomInt类成员函数中使用超过一次的逻辑代码 段定义成相应的内部操作,即私有成员函数。例如,可以将多个成员函数中需要使用 的将m进制的数值码表示串转换为一个10进制整型数值的操作定义成一个私有成员 函数,该函数可以命名为StrToInt;还可以将多个成员函数中需要使用的将一个10 进制整型数值转换成m进制的数值码表示串的操作也定义成另一个私有成员函数, 该函数可以命名为IntToStr。 4. 类型转换运算函数必须是RandomInt类的成员函数,而算术四则运算符函数必须是 RandomInt类的友元函数,并且每种运算符函数都应有3个不同版本,才能满足题 意的要求。例如,+ 运算符的重载函数应该有3个版本,它们在RandomInt类定义 中原型声明应为如下形式: ... friend RandomInt operator +(const RandomInt&, const RandomInt&); friend RandomInt operator +(const int&, const RandomInt&); friend RandomInt operator +(const RandomInt&, const int&); … 难度等级:**** 题目4 复数在数学、物理和工程领域都有广泛的应用,例如,电路中阻抗就是用复数表示的, 复数的实部表示阻抗中的电阻性部分,而阻抗中的电感性和电容性部分则用复数的虚部 表示。 复数的一般表示形式为z = x + iy 其中x表示复数的实部,y表示复数的虚部,i2 = -1。 因此一个实数可以是虚部为0的复数,例如f + i0。 复数的模|z| = Magnitude(z) =√(x2 + y2)。 复数的辐角Argz = Arctg(y / x),因此一个复数无穷多个辐角,但其中一个称为主辐角, 记作argz,它满足0 ≤argz< 2π,并有Argz = argz + 2kπ (k = 0, ±1, ±2,„)。 一个复数的共轭复数 z  = conjugate(z) = x–iy。 复数的算术运算规则如下: 若令u = a + ib,v = c + id,则: 加:u + v = (a + c) + i(b + d) 减:u – v = (a – c) + i(b – d) 乘:u * v = (a*c – b*d) + i(b*c + a*d) 除:u / v = (a*c + b*d) / (c2 + d2) + i((b*c – a*d) / (c2 + d2)) 求反:–u = –a + i(–b) 要求: 1.定义并实现复数类Complex,该类应该包含如下属性和操作: 属性: ① 实部属性real:double类型的私有数据成员,用于表示复数的实部。 ② 虚部属性imag:double类型的私有数据成员,用于表示复数的虚部。 操作: ① 构造函数:具有两个double类型的参数分别用于为real和imag传递初始值, 这两个参数的缺省值均为0.0。 ②算术运算操作:能使用二目算术四则运算符 „+‟„-„„*‟„/‟和单目求反运算符 „-„实 现复数的算术运算操作。参与二目算术四则运算的两个操作数中允许有一个实数。 运算符函数的返回值均为复数。 ③求模操作Magnitude:用于复数的模计算操作。函数应返回一个表示模的实数。 ④求主辐角操作argz:用于复数的辐角计算操作。函数应返回一个表示角度的实数。   ⑤ 共轭操作conjugate:用于求一个复数的共轭复数操作。函数应返回一个复数。 ③输入、输出操作:能对标准输入流cin使用输入运算符>>和对标准输出流cout 使用输入运算符<<进行复数的输入和输出操作。复数的输入、输出形式应符合复 数的标准表示形式x + iy。 ④ 实部属性访问操作GetReal:用于获取复数的实部值。 ⑤ 虚部属性访问操作GetImag:用于获取复数的虚部值。 2.定义一个类外全程函数Distanc: double Distance(Complex&a, Complex&b); 用于计算复平面中两个复数之间的距离。 3.在main()函数中完成对复数类Complex的以下验证操作: ① 定义并显示三个复数Complex对象。 ② 验证i2 = –1。 ③ 分别计算、对比和显示3个复数和它们共轭的模、辐角。(注意,输出格式) ④ 调用全程函数Distance计算并显示已定义的三个复数点在复平面上相互之间的 距离。 ④ 定义函数f(z),求复数多项式函数的根。求解的复数多项式如下:   z3 – 3z2 + 4z – 2  用下列z值,分别求多项式的值,判断并显示哪些个z是f(z)的根:   z = 2 + 3i,–1 + i,1 + i,1 – i,1 + 0i *4.要求编写编程文档,文档内容包括:(选作)  ① Complex类图 ② Complex类定义描述 ③ 重要类成员函数和全程类外函数Distance的实现算法描述  ④ main()函数的流程图 提示: 1. 一个复数相当于复数平面中的一个点: y u=a+ib a c |u|O b |v|v=c+id d x 因此,两个复数之间的距离相当于平面上两个点之间的距离。 2. 算术四则运算符函数必须是Complex类的友元函数。由于Complex类的构造函 数能将一个实数隐含转换为Complex类对象,因此不必为每种运算符函数定义多个 不同版本,就能满足题意的要求。 3.当多项式的值为0时,则z为f(z) 的根。 难度等级:*** 题目5 有理数是分数p/q的集合,其中p、q均为整数且q ≠ 0,p称为分子,q称为分母。 1. 有理数的表示: 一个有理数表示的是分子p占分母q的比例,因此,可以用许多等值的分数p/q来 表示同一个有理数,例如:2/3 = 10/15 = 50/75。 这些等值分数数中,必定有一个为最简,即该分数的分子和分母没有大于1的公因 子,因此有理数的标准表示形式应该是最简分数。有理数中,分子和分母均可为负 整数,但在标准化的有理数表示中我们总是以分母为正的形式表示。 2.有理数的算术运算: 按照分数的四则运算规则进行,运算的结果仍为有理数(即用标准的有理数表示) 加法:(a/b) + (c/d) = (a*d + c*b) / b*d 减法:(a/b) - (c/d) = (a*d - c*b) / b*d 乘法:(a/b) * (c/d) = (a*c)/ (b*d) 除法:(a/b) / (c/d) = (a*d)/ (b*c) 求反:-(a/b) = -a / b 3.有理数的关系运算:  所有的关系运算都用一个统一的原则:首先将两个参与运算的有理数通分(即求分母 相同的等值数),然后比较它们的分子。例如: (a/b) ≤ (c/d) = (a*d) ≤ (c*b) „ 要求: 1.实现以下有理数类Rational定义,该类应该包括以下属性和操作: 属性:   ① 分子属性num:存放标准表示形式有理数的分子。考虑有理数的数值表示范围, 该属性应声明为long类型。 ② 分母属性den:存放标准表示形式有理数的分母。考虑有理数的数值表示范围, 该属性应声明为long类型。 操作:  ①构造函数:有理数的构造应该能适应以下三种情况: ·不指定分子、分母(例如构造有理数数组)构造有理数; ·指定整数分子、分母构造有理数; ·将一个指定的实数转换构造成有理数。 为了适应前两种情况的需要,可以定义一个传递有缺省值的指定分子、分母参数 的构造函数,分子的缺省值 = 0,分母的缺省值 = 1。(参数类型为long类型) 有理数对象构造时,属性num = 分子参数,den= 分母参数。 而满足第3种情况,则需要定义一个传递实数(double)类型参数的构造函数。 有理数对象构造时,需将实数参数等值变换为分数形式,并使属性num = 分子, den= 分母。 无论上述哪一个构造函数,在为属性赋值后都必须进行对分子、分母的合法性检 查(den≠ 0)和标准化(求最简分数和分母正数化)操作。 ② 算术运算操作:能使用二目算术四则运算符 „+‟„-„„*‟„/‟和单目求反运算符 „-„实 现有理数的算术运算操作。参与二目算术四则运算的两个操作数中允许有一个实 数。运算符函数的返回值均为有理数。 ③ 关系运算操作:能使用二目关系运算符 „<‟„<=„„==‟„!=‟„>‟„>=„实现两个有理数 之间的各种相应的关系运算。参与关系运算的两个操作数中允许有一个实数。关 系运算符函数的返回值均为表示比较结果的整型(int)数值。 ④ 输入、输出操作:能对标准输入流cin使用输入运算符>>和对标准输出流cout 使用输入运算符<<进行有理数的输入和输出操作。有理数的输入、输出形式应符 合有理数的标准表示形式a/b。 ⑤ 类型转换操作:将有理数转换为一个实数(double)数值,并返回。    ⑥ 获取分子属性GetNumerator:返回有理数的分子属性值num。   ⑦ 获取分母属性GetDenominator:返回有理数的分母属性值den。   ⑧ 有理数标准化操作Standardize:对有理数进行标准化(分数最简化和分母整数 化)操作。该操作在有理数类的构造函数、算术运算操作和输入操作中都需要调 用,但不会在有理数类外被调用,因此它只需被声明为类的私有成员函数。标准 化操作中的分数最简化操作需要求分子属性num和分母属性den的最大公约数, 可以将求最大公约数的操作定义为另一个私有函数。 ⑨ 求两数的最大公约数操作:计算两个整数的最大公约数,并返回计算结果。 被计算的两个整数有参数传入操作。参数和返回类型均为long类型。 2.定义一个类外全程函数:  Rational SolveEquation(Rational A, Rational B, Rational C);    用于求解一般形式为: a  2c  e x +  x =  b d f 的有理方程 3. 在main()函数中完成对有理数类Rational的以下验证操作: ① 对有理数类的各项算术操作和关系运算进行验证。 ② 格式输入有理方程的系数,建立一个有理方程,调用SolveEquation求解方程,  并格式显示方程的解。 ③ 声明实数pi = 3.14159265和pi的有理数近似值Rational(22,7),然后进行如下 计算: ·计算将这两个数作为有理数时的差:Rational(pi) – Rational(22,7)   ·计算将这两个数作为实数时的差:pi – double(Rational(22,7)) *4.要求编写编程文档,文档内容包括:(选作)    ① Rational类图 ② Rational类定义描述 ③ 重要类成员函数和全程类外函数SolveEquation的实现算法描述   ④ main()函数的流程图 提示: 1. 把一个实数r转换成分数形式p/q的方法是经过r ->r/1 -> (r×N)/(1×N) ->p/q等值 变换完成。变换因子N的选择原则是使r消除小数位成为整数,而不损失精度,因 此应将N(N为long类型)选择得足够大,例如,r = 3.567, 则N = 1000L。 2. 两个整数的最大公约数可以通过辗转相除法计算获得。 3. 算术四则运算符函数可以是Rational类的友元函数。由于Rational类的构造函数 能将一个实数隐含转换为Rational类对象,因此不必为每种运算符函数定义多个 不同版本,就能满足题意的要求。 难度等级:*** 题目6 集合是由从被称为全集(universal set)的一组对象中选出的若干对象组成(例如,1 个整数集合就是从整数全集中选出的若干无重复的整数组成的)。我们将集合写成表的 形式,并以逗号为间隔,用大括号将两恻括起来。  X = {I1, I2, I3, „ Im} 集合的主要运算包括: ·并集(∪):X∪Y是不重复地包含X中所有元素和Y中所有元素的集合。例如: X = {0,3,20,55} Y = {4,20,45,55} X∪Y = {0,3,4,20,45,55} ·交集(∩):X∩Y是所有既在X中又在Y中的元素的集合。 X = {0,3,20,55} Y = {4,20,45,55} X∩Y = {20, 55} ·属于集合(∈):如果元素n是集合X的成员,则n∈X为真;否则为假。例如:  X = {0, 3, 20, 55}   // 20∈X为真,35∈X为假。 要求: 1.定义一个整数集合类Set,要求该类包含如下属性和操作: 属性:   ① 元素表属性member[SETSIZE]:是从0 „ SETSIZE– 1范围内的整数中选出 的元素表,其中SETSIZE指定整数元素值和表中可以容纳的元素个数的范围, 例如,可以在类外定义: const int SETSIZE = 500;。 注意,元素表member的元素值只有两种状态(非true即false)。如果元素n 对应的元素表的元素值为真(true),则表示n在集合中,即n∈X当且仅当 member[n] 为真。 例如,集合X = {1,4,5,7}对应的元素表中,只有元素member[1],member[4], member[5],member[7]为真,而其余元素均为假。  false true false false trur true false true false false „ false  „ 0 2 3 5 6 8 9 499 1 4 7 操作: ① 构造函数:构造Set类对象分两种情况:    ·如果不通过参数传递初值,则在集合对象的构造过程中,元素表member的各 个元素被缺省设置为false,即空元素表。 ·如果将一个整型数组a[]和数组的元素个数n作为参数传递初值,则在集合对象 的构造过程中,元素表中由数组a[]的元素值作为下标的元素值被设置为true, 而其他元素设置为false。 ② 插入元素操作Insert:通过参数将一个在0 „ SETSIZE– 1范围内的整数n插 入集合中,即member[n] = true。 ③ 删除元素操作Delete:通过参数将一个在0 „ SETSIZE– 1范围内的整数n从 集合中删除,即member[n] = false。 ④ 并集运算操作operator+:将两个Set对象表示的整数集合进行并集运算,并返 回结果集合。 ⑤ 交集运算操作operator*:将两个Set对象表示的整数集合进行交集运算,并返 回结果集合。 ⑥ 属于集合运算操作operator^:判断一个整数元素是否属于一个指定的Set对象 表示的整数集合,并返回结果标志(非true即false)。被判断的整数元素和整数 集合通过参数传递给操作。 ⑦ 输出操作:通过标准输出流cout,按集合的表示格式输出显示整数集合。 2. 编写一个类外全程函数int fillSet();,该函数的功能是:   ·创建一个集合(Set对象)p; ·产生5个0 – 4的随机数,并顺序插入集合p; ·使用集合的属于集合运算操作operator^分别检测集合p,如果0,1,2,3, 4是否都 属于集合p,则返回1;否则返回0。 3. 在main()函数中,通过如下对Set类对象的使用,全面检测Set类的正确性。 ① 创建以下集合: S = {1, 5, 7, 12, 24, 36, 45, 103, 355, 499} T = {2, 3, 5, 7, 8, 9, 12, 15, 36, 45, 103, 255, 355, 498} U = {1, 2, 3, 4, 5, …, 50} 其中S和T 通过构造函数完成对集合的初始化;而U要求使用Insert进行初始 化。 ② 计算并显示S + T。 ③ 计算并显示S * T。 ④ 计算并显示S * U。 ⑤ 从T中删除8,36,103和498,并在删除操作的前后分别显示T,以便比较删 除操作的结果。 ⑥ 生成并显示一个1到9之间的随机数,然后验证它是否在集合S中,并显示验证 结果(这样的操作过程连续做5次)。 ⑦使用Set对象模拟在0到4范围内连续随机抽取5次得到5个不同数的概率,此 数学概率为:1×4/5×3/5×2/5×1/5 = 0.0384。为此,调用全程函数fillSet 100000 次,并累计返回值,用以验证上述数学概率。 提示: 1. 随机数的产生方法需要调用库函数srand和rand,具体方法可以参考第3章编程练 习题中3-5扑克牌游戏的洗牌操作中的相关提示。 2. 集合的并集operator+、交集operator*和属于集合operator^操作运算符既可以定 义为成员函数,也可以定义友员函数。注意,如果这些运算符函数被定义为成员函数, 则应该声明为只读函数。 难度等级:**** 题目7 日期类Date的定义如下: class Date {   int month;      // 月份值 int day;       // 日值 intyear;       // 年份值 string format;     // 输出格式描述串 public:   Date(int m = 1, int d = 1, int y = 0);  // 使用参数值为相应的属性month,day和 //year赋初值。各参数值的范围: // 1≤m≤12,1≤d≤31,0≤y≤600; // 在为各属性赋值之前,需要根据上述范围 // 对各参数值进行合法性检查;其中对参数d // 的合法性检查还需要根据m和y的值进行 // 闰年、闰月和大小月份的判断。如果参数 // 值超越了合法值的上界或下界,则自动修 // 改为相应值的上界或下界。注意,属性 //year=1900+y。 // 使用缺省参数时,各属性被赋值为: //month=1,day=1,year=1900。 // 无论是否使用缺省参数值,format都缺省 // 设置为”mm/dd/yy”。 Date(string dstr);     // 将参数传送的格式日期字串”mm/dd/yy”转 // 换为相应的年、月、日值、进行合法性检 // 查后为相应的属性赋值。例如,日期字串 //“12/31/99” 将被转换、合法性检查和赋值 // 为:month=12,day=31,year=1999, // 如果dstr=””,则将各属性被赋值为: //month=1,day=1,year=1900。 // 注意,参数dstr不允许等于0。 // 无论dstr是否为””,format都缺省设置为 //”mm/dd/yy”。 intoperator>(Date date) const; // 按照日期大小规则比较两个Date对象所表 // 示的日期,如果*this>date,返回1;否 // 则返回0。 intoperator<=(Date date) const; // 按照日期大小规则比较两个Date对象所表 // 示的日期,如果*this≤date,返回1;否 // 则返回0。 intoperator!=(Date date) const; // 按照日期大小规则比较两个Date对象所表 // 示的日期,如果*this≠date,返回1;否 // 则返回0。 Date operator+(long days) const; // 创建新Date对象date=*this+days,并返 // 回date。运算按照日期增加的规则进行, // 例如, 2005年5月20日+100日 = 2005 // 8月28日。如果运算结果超越了日期表示 // 上界2500年12月31日,则自动调整运算 // 结果等于日期表示上界。 Date operator-(long days) const; // 创建新Date对象date=*this-days,并返 // 回date。运算按照日期增加的规则进行, // 例如, 2005年5月20日-100日 = 2005 // 2月9日。如果运算结果超越了日期表示 // 下界1900年1月1日,则自动调整运算 // 结果等于日期表示下界。 void Format(string fmt);   // 使用参数fmt传递的格式串为输出格式属 // 性format赋值。允许的输出格式有两种: //”mm/dd/yy”或”yy年mm月dd日”。 friend ostream&operator<<(ostream&out, Date date);         // 按照输出格式属性format确定的格式, // 通过标准输出流输出显示Date对象所表 // 示的日期。例如,date的各日期属性值为: // month=12,day=31,year=2005。 // 如果format=”mm/dd/yy”,则date的输出 // 字串为”12/31/2005”; // 如果format=”yy年mm月dd日”,则date //的输出字串为”2005年12月31日”。 }; 要求: 1. 实现Date类的各成员函数的操作功能。 2. 在main()函数中,通过如下对Date类对象的使用,全面检测Date类的正确性。 ① 定义下列日期对象: Date(5,5,77);  Date(10,24,73);  Date(“12/25/44”);  Date(9,30,82);  Date(3,5,105);  Date(3,7,105); ② 使用所定义的比较运算符对上述日期对象进行相互比较,并显示被比较的日期 和比较结果提示。例如: Date(5,5,77) >Date(10,24,73)  Date(“12/25/44”) <= Date(9,30,82)  Date(3,5,105) != Date(3,7,105) ③ 检测所定义的+ -运算操作,并显示运算结果产生的新日期。 ④ 依次修改所定义的日期对象的输出格式为”yy年mm月dd日”,并按新格式逐个 显示日期对象。 难度等级:*** 题目8 从下图可以看出一个立方体Box可以视为是在一个矩形Rectangle的相互正交的长 length和宽width的基础上增加一维与length和width相互正交的高height而生成 的。Box的体积可以视为是由length和width确定的矩形面积沿正交轴在[0, height] 区间进行积分获得的;Box的面积可以视为是由length和width确定的矩形周长沿正 交轴在[0, height]区间进行积分的结果+两倍的矩形面积获得的。 Rectangle width length  Box height width length 要求: 1.定义具有继承关系的矩形类Rectangle和立方体类Box。两个类中除了具有共同的 属性length和width,还具有相同的接口(公有成员函数)Area(计算矩形面积 或立方体面积),Perimeter(计算矩形周长或立方体周长),Diagonal(计算矩形 对角线或立方体对角线的长度),GetLength(获取长度属性),GetWidth(获取宽 度属性),SetLength(设置长度属性)和SetWidth(设置宽度属性)。除此之外, 立方体类Box还需要增加height属性和接口函数Volume(计算立方体的体积), GetHeight(获取高度属性)和SetHeight(设置高度属性)。 2. 在主函数main()中对矩形类Rectangle和立方体类Box进行如下测试: ① 通过键盘输入长、宽和高,并以所输入的值创建3个Rectangle对象和1个Box 对象。 ② 通过上述对象分别计算并格式显示3个矩形和1个立方体的各项形态信息。矩 形的形态信息包括:长、宽、面积、周长和对角线;立方体的形态信息包括:长、 宽、高、体积、面积、周长和对角线。 ③ 通过键盘输入新的长、宽和高,由并以所输入的值修改已创建的3个Rectangle 对象和1个Box对象的相应属性。 ④ 重新分别计算并格式显示3个矩形和1个立方体的各项形态信息。 3. 要求编写编程文档,文档内容包括: ① 绘制Rectangle和Box类图,以及它们之间的静态关联图。    ② Rectangle和Box类的定义描述。 提示: 1. 立方体的周长定义为各棱长的和,立方体的对角线定义为立方体中不在同一矩形表 面的两个顶点间的连线(矩形的对角线是不在同一边上的两个顶点间的连线)。 难度等级:*              
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务
