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