1、中级软件设计师下午试题-22 及答案解析(总分:90.00,做题时间:90 分钟)一、试题一(总题数:1,分数:15.00)1.【说明】流程图描述了某高校图书订购与编目系统的处理流程。全校的图书典藏在校图书馆和各系的资料室中。学校每年分若干批向出版单位订购图书,同一批订购的图书将陆续邮寄到学校。出版单位在寄出图书的同时附上到书清单和发票,发票上仅给出一份到书清单中书的总册数和总金额。学校收到图书和发票后,先参照订购单验收,然后进行编目,并把有关信息存放在书种文件、书名文件、作者文件和复本文件中,以供读者检索。书种文件记录了每种书的有关信息。所谓一种书是指同一作者、同一书名、同一出版单位和同一出
2、版年份出版的书。例如,2004 年张明在科技出版社出版了软件工程(印数 8000 册)和数据库基础(印数5000 册),则张明在 2004 年出版了两种书。在全校的藏书中,如果一种书只有一册,则该书的信息存放在书种文件中:如果一种书有多册,则其中一册书的信息存放在书种文件中,其余的书作为复本将信息存放在复本文件中。复本文件的结构与书种文件的结构相同,每种书都有一个书号,书号唯一地标识了一种书。在书库中,每册书有一个登录号,登录号唯一地标识了一册书。此外,为了图书检索的方便,将图书按学科分类,分类号用来标识不同的学科领域。各类单据和文件的结构如下所示。订购单:订购批号、书名、作者名、出版单位、出
3、版年份、单价、订购册数、订购部门代码、订购日期。到书清单:订购批号、书名、作者名、出版单位、出版年份、单价、册数。发票:订购批号、发票号、总册数、总金额。书种文件:分类号、登录号、书名代码、作者代码、出版单位、出版年份、单价、复本标志、典藏部门代码、借出标志。其中,复本标志用来指示该种书在书库中有没有复本:对于书名相同的若干种书,书名代码是相同的。书名文件:书名代码、书名。作者文件:作者代码、作者名。【问题 1】指出验收文件至少应由哪些数据项组成。【问题 2】由于处理 5 和处理 6 的分类,可能导致分类后的文件中一张发票无法找到与它对应的那些书,从而当一组发票的金额之和与一组到书清单中的书价
4、之和不等时,无法知道是哪一张发票和哪一份清单不一致。如果仍使用原流程图,那么当到书清单文件的结构做何改动后,能找出不一致的发票和相应的书目。(分数:15.00)_二、试题二(总题数:1,分数:15.00)2.【说明】在一个航空公司的航班管理系统中,有以下一些事实。(1)一个航班可能是一个或多个乘客的运输工具,每个乘客可能是一个或多个航班的旅客。(2)一个且仅一个飞行员必须对每个航班负责,每个飞行员可能负责一个或多个航班。(3)一个或多个飞行员必须对每个乘客负责,每个飞行员必须对一个或多个乘客负责。现有飞行员的实体如下:飞行员(飞行员编号,航班编号,姓名,工资,起飞地,到达地,飞行信用时间)说明
5、:飞行信用时间是一个特定的航班分配给一名飞行员,授权他可以驾驶管理这个航班。【问题 1】实体“飞行员”是否符合 1NF,如果不符合,如何将它规范化。【问题 2】由问题 1 得到的实体“飞行员”是否符合 2NF,如果不符合,如何将它规范化。【问题 3】指出最后得到关系模式的候选码。(分数:15.00)_三、试题三(总题数:1,分数:15.00)3.【说明】银行客户需要从 ATM 取 100 元,他向 ATM 的读卡机插卡,读卡机读取他的卡号,然后 ATM 屏幕初始化,ATM 提示输入密码,客户输入密码(123456),ATM 打开他的账户,密码有效,因此 ATM 提示选择事务,客户选择取钱,AT
6、M 提示输入金额,客户输入 100 元,ATM 验证账户上有足够的钱,就从账上减去 100 元,ATM 吐出 100 元,并退出的卡。【问题】根据上面的描述,在下面填写,完成未完成的协作图。1插卡(客户一读卡机)2_(_)3_(_)4提示输入 PIN (123456) (ATM 显示屏客户)5_(_)6_(_)7验证 PIN(_)8提示选择事务(_)9_(客户ATM 屏幕)10提示金额(ATM 屏幕客户)11输入金额(客户ATM 屏幕)12取钱(ATM 屏幕的账户)13_(_)14_(_)15_(_)16提供收据(客户的账户取钱机)17_(_)(分数:15.00)_四、试题四(总题数:1,分数
7、:15.00)4.【说明】本程序从正文文件 text.in 中读入一篇英文短文,统计该短文中不同单词及出现次数,并按词典编辑顺序将单词及出现次数输出到正文文件 wordout 中。程序用一棵有序二叉树存储这些单词及其出现的次数,边读入边建立,然后中序遍历该二叉树,将遍历经过的二叉树上的结点的内容输出。#include stdio.h#include malloc.h#include ctype.h#include string.h#define INF “text.in“#define OUTF “wotd.out“typedef struct treenodechar *word;int c
8、ount;struct treenode *left,*right;BNODEint getword (FILE *fpt,char *word)char c;c=fgetc (fpt);if ( cEOF)return 0;while(!(tolower(c)=a void binary_tree(BNODE *t,char *word)BNODE *ptr,*p;int compres;P=NULL; (1) ;while (ptr) /*寻找插入位置*/compres=strcmp (word, (2) );/*保存当前比较结果*/if (!compres)(3) ;return;els
9、e(4) ;ptr=compres0? ptr-right:ptr-left;ptr= (BNODE*) malloc (sizeof (BNODE) ;ptr-left = ptr-right = NULL;ptr-word= (char*) malloc (strlen (word) +1) ;strcpy (ptr-word, word);ptr-count - 1;if (p=NULL)(5) ;else if (compres 0)p-right = ptr;elsep-left = ptr;void midorder (FILE *fpt, BNODE *t)if (t=NULL)
10、return;midorder (fpt, t-left);fprintf (fpt, “%s %d/n“, t-word, t-count)midorder (fpt, t-right);void main()FILE *fpt; char word40;BNODE *root=NULL;if (fpt=fopen (INF,“r“) =NULL)printf (“Cant open file %s/n“, INF )return;while (getword (fpt, word) =1 )binary_tree (fclose (fpt);fpt = fopen (OUTF, “w“);
11、if (fpt=NULL)printf (“Cant open file %s/n“, OUTF)return;midorder (fpt, root);fclose(fpt);(分数:15.00)_五、试题五(总题数:1,分数:15.00)5.【说明】Point 是平面坐标系上的点类,Line 是从 Point 派生出来的直线类。#include iostream.hclass Pointpublic:Point (int x, int y) ;Point (Point Point();void set (double x, double y) ;void print();private:d
12、ouble X,Y;Point:Point (int x, int y) /Point 构造函数X=x; Y=y; Point:Point ( (1) ) /Point 拷贝构造函数X=p.X; Y=p.Y;void Point:set (double x, double y)X=x; Y=y; void Point:print()cout (X“,“Y“) “endl; Point:Point()cout“Point 的析构函数被调用! “endl;class Line: public Pointpublic:Line (int x, int y, int k) ;Line (Line Li
13、ne();void set (double x, double y, double k)void print();private:double K;(2) /Line 构造函数实现K=k;(3) /Line 拷贝构造函数实现K=s.K;void Line:set (double x, double y, double k)(4) ;K=k;void Line:print()cout“ 直线经过点“;(5) ;cout“斜率为: k=“Kendl;Line: :Line()cout“Line 析构函数被调用! “endl;void main()Line 11 (1,1,2) ;11 .print
14、();Linel2 (11) ;12.set (3,2,1) ;12.print();(分数:15.00)_六、试题六(总题数:1,分数:15.00)6.【说明】一条直线是由两个点组成的,代码如下。public class Pointprivate int x, y; /coordinatepublic Point (int x, int y)(1) =x; (2) ;public int GetX()return x; public int GetY()return y; class Line /line segmentprivate (3) ; /extremc pointsLine (P
15、oint a, Point b) /constructorp1 = (4) ;p2= (5) ;public double Length() return Math.sqrt (Math.pow (p2.GetX()-pl.GetX(),2)+Math.pow (p2.GetY()-p1.GetY(),2) ;(分数:15.00)_中级软件设计师下午试题-22 答案解析(总分:90.00,做题时间:90 分钟)一、试题一(总题数:1,分数:15.00)1.【说明】流程图描述了某高校图书订购与编目系统的处理流程。全校的图书典藏在校图书馆和各系的资料室中。学校每年分若干批向出版单位订购图书,同一批
16、订购的图书将陆续邮寄到学校。出版单位在寄出图书的同时附上到书清单和发票,发票上仅给出一份到书清单中书的总册数和总金额。学校收到图书和发票后,先参照订购单验收,然后进行编目,并把有关信息存放在书种文件、书名文件、作者文件和复本文件中,以供读者检索。书种文件记录了每种书的有关信息。所谓一种书是指同一作者、同一书名、同一出版单位和同一出版年份出版的书。例如,2004 年张明在科技出版社出版了软件工程(印数 8000 册)和数据库基础(印数5000 册),则张明在 2004 年出版了两种书。在全校的藏书中,如果一种书只有一册,则该书的信息存放在书种文件中:如果一种书有多册,则其中一册书的信息存放在书种
17、文件中,其余的书作为复本将信息存放在复本文件中。复本文件的结构与书种文件的结构相同,每种书都有一个书号,书号唯一地标识了一种书。在书库中,每册书有一个登录号,登录号唯一地标识了一册书。此外,为了图书检索的方便,将图书按学科分类,分类号用来标识不同的学科领域。各类单据和文件的结构如下所示。订购单:订购批号、书名、作者名、出版单位、出版年份、单价、订购册数、订购部门代码、订购日期。到书清单:订购批号、书名、作者名、出版单位、出版年份、单价、册数。发票:订购批号、发票号、总册数、总金额。书种文件:分类号、登录号、书名代码、作者代码、出版单位、出版年份、单价、复本标志、典藏部门代码、借出标志。其中,复
18、本标志用来指示该种书在书库中有没有复本:对于书名相同的若干种书,书名代码是相同的。书名文件:书名代码、书名。作者文件:作者代码、作者名。【问题 1】指出验收文件至少应由哪些数据项组成。【问题 2】由于处理 5 和处理 6 的分类,可能导致分类后的文件中一张发票无法找到与它对应的那些书,从而当一组发票的金额之和与一组到书清单中的书价之和不等时,无法知道是哪一张发票和哪一份清单不一致。如果仍使用原流程图,那么当到书清单文件的结构做何改动后,能找出不一致的发票和相应的书目。(分数:15.00)_正确答案:(问题 1书名、作者名、出版单位、出版年份、单价、册数、订购部门代码(或典藏部门代码)。问题 2
19、在到书清单中增加“发票号”。问题 3书号、登录号、典藏部门代码、借出标志。)解析:解析 阅读流程图,可以看出验收文件是一个中间文件,既有数据来源,又要提供数据给其他文件,数据来源是订购单文件、发票文件和到书清单文件,所以它的数据项应该由这 3 个文件直接或间接处理产生。验收文件还要用于在处理 8 更新书种文件、书名文件、作者文件和复本文件 4 个文件,所以它的数据项还要保证处理 8 能够更新这 4 个文件,即这 4 个文件没有,但更新又需要的数据项。比照涉及到的各个文件的数据项组成,可以推出,验收文件至少应该包含书名、作者名、出版单位、出版年份、单价、册数、订购部门/典藏部门代码等数据项。问题
20、 2 内容很长,看起来很复杂,其实就是关于“发票”对号的问题,所以,稍加分析,可以得出结论:在到书清单中增加“发票号”。由说明可知,每种书都有一个书号,书号唯一地标识了一种图书。一种图书的不同复本的著录信息是相同的,但登录号对于每一册图书是唯一的,典藏部门代码和借出标志也是针对某一册图书而有所不同的。所以,在书种文件中增加数据项“书号”后,复本文件中关于该种图书的出版发行信息及分类号,书名代码、作者代码等的数据项可以删除而不影响系统的功能。二、试题二(总题数:1,分数:15.00)2.【说明】在一个航空公司的航班管理系统中,有以下一些事实。(1)一个航班可能是一个或多个乘客的运输工具,每个乘客
21、可能是一个或多个航班的旅客。(2)一个且仅一个飞行员必须对每个航班负责,每个飞行员可能负责一个或多个航班。(3)一个或多个飞行员必须对每个乘客负责,每个飞行员必须对一个或多个乘客负责。现有飞行员的实体如下:飞行员(飞行员编号,航班编号,姓名,工资,起飞地,到达地,飞行信用时间)说明:飞行信用时间是一个特定的航班分配给一名飞行员,授权他可以驾驶管理这个航班。【问题 1】实体“飞行员”是否符合 1NF,如果不符合,如何将它规范化。【问题 2】由问题 1 得到的实体“飞行员”是否符合 2NF,如果不符合,如何将它规范化。【问题 3】指出最后得到关系模式的候选码。(分数:15.00)_正确答案:(问题
22、 1航班(航班编号,起飞地,到达地)飞行员(飞行员编号,航班编号,飞行员姓名,工资,飞行信用时间)问题 2飞行员(飞行员编号,飞行员姓名,工资)信用时间(飞行员编号,航班编号,信用时间)问题 3航班一航班编号;飞行员飞行员编号:信用时间飞行员编号,航班编号)解析:解析 为了将飞行员实体转换成 1NF,必须将它划分成两个实体:飞行员和航班。航班(航班编号,起飞地,到达地)飞行员(飞行员编号,航班编号,飞行员姓名,工资,飞行信用时间)问题 1 中得到的飞行员实体不属于 2NF,因为尽管复合键是(Flight-Id,Pilot-Id),但是 Flight-Time-Credited 是只依赖于 Fl
23、ight-Id,而不依赖于 Pilot-Id。因此,应将它划分为两个实体,即飞行员和信用实现。如下:飞行员(飞行员编号,飞行员姓名,工资)信用时间(飞行员编号,航班编号,信用时间)三、试题三(总题数:1,分数:15.00)3.【说明】银行客户需要从 ATM 取 100 元,他向 ATM 的读卡机插卡,读卡机读取他的卡号,然后 ATM 屏幕初始化,ATM 提示输入密码,客户输入密码(123456),ATM 打开他的账户,密码有效,因此 ATM 提示选择事务,客户选择取钱,ATM 提示输入金额,客户输入 100 元,ATM 验证账户上有足够的钱,就从账上减去 100 元,ATM 吐出 100 元,
24、并退出的卡。【问题】根据上面的描述,在下面填写,完成未完成的协作图。1插卡(客户一读卡机)2_(_)3_(_)4提示输入 PIN (123456) (ATM 显示屏客户)5_(_)6_(_)7验证 PIN(_)8提示选择事务(_)9_(客户ATM 屏幕)10提示金额(ATM 屏幕客户)11输入金额(客户ATM 屏幕)12取钱(ATM 屏幕的账户)13_(_)14_(_)15_(_)16提供收据(客户的账户取钱机)17_(_)(分数:15.00)_正确答案:(1插卡(客户读卡机)2读卡号(读卡机读卡机)3屏幕初始化(读卡机ATM 屏幕)4提示输入 PIN(ATM 显示屏客户)5输入 PIN(12
25、3456)(客户ATM 屏幕)6打开账户(ATM 屏幕客户的账户)7验证 PIN(ATM 屏幕客户的账户)8提示选择事务(ATM 屏幕客户)9选择事务(取钱)(客户ATM 屏幕)10提示金额(ATM 屏幕客户)11输入金额(100 元)(客户ATM 屏幕)12取钱(100 元)(ATM 屏幕客户的账户)13验钱(100 元)(客户的账户客户的账户)14扣钱(100 元)(客户的账户客户的账户)15提供钱(100 元)(客户的账户取钱机)16提供收据(客户的账户取钱机)17退卡(客户的账户读卡机)解析:解析 这道题和模拟试题 4 中的试题 3 是相似的,一个需求描述的时序图和协作图是可以相互转换
26、的,所以,这个取钱过程的时序图的分析方法同样可以用在协作图的分析上。根据上述的分析方法并结合题中已经给出的提示可以得出答案,答案如下。四、试题四(总题数:1,分数:15.00)4.【说明】本程序从正文文件 text.in 中读入一篇英文短文,统计该短文中不同单词及出现次数,并按词典编辑顺序将单词及出现次数输出到正文文件 wordout 中。程序用一棵有序二叉树存储这些单词及其出现的次数,边读入边建立,然后中序遍历该二叉树,将遍历经过的二叉树上的结点的内容输出。#include stdio.h#include malloc.h#include ctype.h#include string.h#d
27、efine INF “text.in“#define OUTF “wotd.out“typedef struct treenodechar *word;int count;struct treenode *left,*right;BNODEint getword (FILE *fpt,char *word)char c;c=fgetc (fpt);if ( cEOF)return 0;while(!(tolower(c)=a void binary_tree(BNODE *t,char *word)BNODE *ptr,*p;int compres;P=NULL; (1) ;while (pt
28、r) /*寻找插入位置*/compres=strcmp (word, (2) );/*保存当前比较结果*/if (!compres)(3) ;return;else(4) ;ptr=compres0? ptr-right:ptr-left;ptr= (BNODE*) malloc (sizeof (BNODE) ;ptr-left = ptr-right = NULL;ptr-word= (char*) malloc (strlen (word) +1) ;strcpy (ptr-word, word);ptr-count - 1;if (p=NULL)(5) ;else if (compre
29、s 0)p-right = ptr;elsep-left = ptr;void midorder (FILE *fpt, BNODE *t)if (t=NULL)return;midorder (fpt, t-left);fprintf (fpt, “%s %d/n“, t-word, t-count)midorder (fpt, t-right);void main()FILE *fpt; char word40;BNODE *root=NULL;if (fpt=fopen (INF,“r“) =NULL)printf (“Cant open file %s/n“, INF )return;
30、while (getword (fpt, word) =1 )binary_tree (fclose (fpt);fpt = fopen (OUTF, “w“);if (fpt=NULL)printf (“Cant open file %s/n“, OUTF)return;midorder (fpt, root);fclose(fpt);(分数:15.00)_正确答案:(解析 (1)ptr=*t本处填空是函数 binary_tree 的开始处,进行初始化,应该是让指针 ptr 指向树的根结点*t。因此应该填入:ptr=*t。(2)ptr-word 或 (*ptr).word 或 ptr0.wo
31、rd本处填空是将要插入的单词 word 与当前指针 ptr 所指的结点的 word 比较大小。(3)ptr-count+本处填空是当要插入的单词 word 与指针 ptr 所指的结点的 word 相同时的处理,必然是将指针 ptr 所指结点的计数器 count 加 1。因此应该填入:ptr-count+。(4)p=ptr本处填空是当要插入的单词 word 与指针 ptr 所指结点的 word 不相同时的处理,必然是让 p 指向 ptr,而ptr 指向其左子树或右子树。因此应该填入:p=ptr。(5)*t=ptr本处填空是当 p 为空时的处理,应该是让树的根结点指针指向 ptr 以便返回。)解析
32、:五、试题五(总题数:1,分数:15.00)5.【说明】Point 是平面坐标系上的点类,Line 是从 Point 派生出来的直线类。#include iostream.hclass Pointpublic:Point (int x, int y) ;Point (Point Point();void set (double x, double y) ;void print();private:double X,Y;Point:Point (int x, int y) /Point 构造函数X=x; Y=y; Point:Point ( (1) ) /Point 拷贝构造函数X=p.X; Y
33、=p.Y;void Point:set (double x, double y)X=x; Y=y; void Point:print()cout (X“,“Y“) “endl; Point:Point()cout“Point 的析构函数被调用! “endl;class Line: public Pointpublic:Line (int x, int y, int k) ;Line (Line Line();void set (double x, double y, double k)void print();private:double K;(2) /Line 构造函数实现K=k;(3) /
34、Line 拷贝构造函数实现K=s.K;void Line:set (double x, double y, double k)(4) ;K=k;void Line:print()cout“ 直线经过点“;(5) ;cout“斜率为: k=“Kendl;Line: :Line()cout“Line 析构函数被调用! “endl;void main()Line 11 (1,1,2) ;11 .print();Linel2 (11) ;12.set (3,2,1) ;12.print();(分数:15.00)_正确答案:(解析 (1)Point /coordinatepublic Point (in
35、t x, int y)(1) =x; (2) ;public int GetX()return x; public int GetY()return y; class Line /line segmentprivate (3) ; /extremc pointsLine (Point a, Point b) /constructorp1 = (4) ;p2= (5) ;public double Length() return Math.sqrt (Math.pow (p2.GetX()-pl.GetX(),2)+Math.pow (p2.GetY()-p1.GetY(),2) ;(分数:15
36、.00)_正确答案:(解析 (1)thisx构造函数 Point 将形参 x 和 y 赋值给当前对象成员 x 和 y,因此必须用 this 指针区别。(2)thisy=y构造函数 Point 将形参 x 和 y 赋值给当前对象成员 x 和 y,因此必须用 this 指针区别。(3)Point p1,p2Point 类的 p1,p2 两个点对象指针,组合成 Line 对象。(4)new Point(aGetX(),aGetY()给 Line 对象的两个点对象指针各自生成对象 Point,并用 a 和 b 点对象为其赋初值。(5)new Point (b.GetX(),b,GetY()给 Line 对象的两个点对象指针各自生成对象 Point,并用 a 和 b 点对象为其赋初值。)解析: