1、中级软件设计师下午试题-11 及答案解析(总分:90.00,做题时间:90 分钟)一、B试题一/B(总题数:1,分数:15.00)1. 【说明】 流程图描述了某宽带数据专线管理系统的部分处理流程。 (1)凡申请宽带数据专线使用者,均需填写专线申请表。系统把申请表存储在专线申请登记文件中,等待分配专线号。 (2)系统为申请者指定专线号,并根据通信距离(按地区计算)、通信计算初装费和月租费,然后发初装通知单送给用户,并产生施工单交有关部门施工。同时产生专线处理文件。专线号是专线的唯一标识。 (3)施工结束后,系统更新用户文件,并产生专线计费文件,作为以后收费的依据。 (4)一个用户可以租用多条专线
2、,用户可用现金或银行托付两种方式支付租金,但一个用户只能使用一种付款方式。系统每月按用户(而不是专线)为单位计费出账。 (5)流程图中各数据文件及有关单据所含的数据项如下。 专线申请表及专线中请登记文件:申请号、用户名称、付款方式,开户银行代码、账号、主端名称、主端地址、对端地址、对端所在地区、通信速率、设备接口、申请日期。 专线处理文件; 申请号、专线号、用户名称、付款方式、开户银行代码、账号、初装费、月租费、完工日期。 初装费收据: 专线号、初装费、交费日期。 施工单: 施工单号、专线号、主端名称、主端地址、对端所在地区,通信速率、设备接口、完工期限。 完工单: 施工单号、专线号、完工日期
3、。 用户文件: 用户编号、用户名称、付款方式、开户银行代码、账号。 专线计费文件: 专线号、用户编号、月租金、开通日期。 【问题 1】 宽带数据专线价目文件由哪些数据项组成? 【问题 2】 为了避免在用户尚未支付初装费时就去施工,有人提议将图中从处理 2 产生的施工单改成从处理 3 产生施工单。试问从处理 3 能否产生施工单?为什么? 【问题 3】 当一个用户使用多条专线时,若允许该用户对其中的一些专线采用现金支付,对另一些专线采用银行托付方式,则在尽量减少数据冗余的前提下,应如何调整有关的数据文件。 (分数:15.00)_二、B试题二/B(总题数:1,分数:15.00)2.【说明】 供应商零
4、件工程项目数据库由以下 4 个关系模式构成: S(SNO,SNAME,STATUS,CITY) P(PNO,PNAME,COLOR,WEIGHT,CITY) J(JNO,TNAME,CITY) SPJ(SNO,PNO,JNO,QTY) 其中,供应商S,零件 P 和工程项目 J 分别由供应商号(SNO),零件号(PNO)和工程项目号(JNO)唯一标识。供货 SPJ 是指由某个供应商向某个工程项目供应某些数量的某种零件。 【问题 1】 请用 SQL 语言完成如下的操作。 找出给北京的工程项目提供不同的零件号: 将没有供货的所有工程项目从 J 中删除; 查询这样的工程项目号:供给该工程项目的零件 P
5、1 的平均供应量大于供给工程项目 n 的任何一种零件的最大供应量。【问题 2】 定义一个视图,它由所有这样的工程项目(工程项目号与所在城市名称)组成:它们由供应商S1 供货且使用零件 P1。(分数:15.00)_三、B试题三/B(总题数:1,分数:15.00)3.【说明】 “进货库存信息管理系统”是 ERP 系统中一个重要的子系统,下面是该系统的一个简化了的主结构功能图。 其中一些各系统功能描述如下: 进货信息管理系统 进货单据建立文件维护管理工作。 进货查询统计管理工作。 进货过账工作。 在进货管理系统中,要处理“成本计算和费用摊消” 的问题。处理方式如下所述。 进口货物的成本计算: (1)
6、先算出本次进货货物的原币总成本金额。 (2)再依照当时原币(如:美金 US$,英镑、港币 HK$等)的汇率乘以本次进货原币总成本金额,算出本次进货台币总成本金额。 (3)再计算出本次进货所产生的全部费用总金额(包含:关税、报关费、运费、其他费用等费用)。 (4)将“本次进货台币总成本金额”加上“全部费用总金额”算出本次实际的“总成本金额”。 (5)再利用下述公式算出各单项货物的“单项货物的成本金额”。 (6)最后一个步骤,再将“单项货物的成本金额”除以单项货物本次进货的数量,即可算出“单一货物本次进货实际的成本金额”。 (分数:15.00)_四、B试题四/B(总题数:1,分数:15.00)4.
7、【说明】 函数 DeleteNode (Bitree *r, int e)的功能是:在树根结点指针为 r 的二叉查找(排序)树上删除键值为 e 的结点,若删除成功,则函数返回 0,否则函数返回-1。二叉查找树结点的类型定义为: typedef struct Tnode int data; /*结点的键值*/ struct Tnode *Lchild, *Rchild; /*指向左、右子树的指针*/ *Bitree: 在二叉查找树上删除一个结点时,要考虑 3 种情况: 若待删除的结点 p 是叶子结点,则直接删除该结点; 若待删除的结点 p 只有一个子结点,则将这个子结点与待删除结点的父结点直接连
8、接,然后删除结点 p; 若待删除的结点 p 有两个子结点,则在其左子树上,用中序遍历寻找关键值最大的结点 s,用结点 s 的值代替结点 p 的值,然后删除结点 s,结点 s 必属于上述、情况之一。 【函数】 int DeleteNode (Bitree *r,int e) Bitree p=*r,pp,s,c; while (U (1) /U) /*从树根结点出发查找键值为 e 的结点*/ pp=p; if(ep-data) p=p-Lchild; else p=p-Rchild; if(!P) return-1; /*查找失败*/ if(p-Lchild p-data=s-data; p=s
9、; /*处理情况、*/ if U(U (4) /U) /Uc=p-Lchild; else c=p-Rchild; if(p=*r) *r=c; else if U(U (5) /U) /Upp-Lchild=c; else pp-Rchild=c; free (p); return 0; (分数:15.00)_五、B试题五/B(总题数:1,分数:15.00)5.【说明】 C+语言本身不提供对数组下标越界的判断。为了解决这一问题,在程序 6 中定义了相应的类模板,使得对厂任意类型的二维数组,可以在访问数组元素的同时,对行下标和列下标进行越界判断,并给出相应的提示信息。 #includeiost
10、ream.h template class T class Array; template class T class ArrayBody friend U (1) /U T* tpBody; int iRows, iColumns, iCurrentRow; ArrayBody (int iRsz, int iCsz) tpBody = U(2) /U iRows = iRsz; iColumns =iCsz; iCurrentRow =-1; public: T row_error=column_error=false; try if (iCurrentRow 0 | iCurrentRo
11、w =iRows) row_error=true; if (j 0 | j =iColumns) column_error=true; if ( row_error=true | column_error = true) U (3) /U catch (char) if (row_error=true) cerr “行下标越界“ iCurrentRow “ “; if (column_error= true ) cerr “列下标越界“ j “; cout “/n“; return tpBodyiCurrentRow * iColumns +j; ; ArrayBody ( ) delete
12、tpBody; ; template class T class Array ArrayBodyT tBody; public: ArrayBodyT Array (int iRsz, int iCsz) : U(5) /U ; void main() Arrayinta1(10,20); Arraydoublea2(3,5); int b1; double b2; b1=a1-510; /有越界提示:行下标越界-5 b1=a11015; /有越界提示:行下标越界10 b1=a114; /没有越界提示 b2=a226; /有越界提示:列下标越界6 b2=s21020; /有越界提示:行下标越界
13、10列下标越界20 b2=a214; /没有越界提示 (分数:15.00)_六、B试题六/B(总题数:1,分数:15.00)6.【说明】下面的程序先构造 Point 类,再顺序构造 Ball 类。由于在类 Ball 中不能直接存取类 Point 中的 xCoordinate 及 yCoordinate 属性值,Ball 中的 toString 方法调用 Point 类中的 toString 方法输出中心点的值。在 MovingBall 类的 toString 方法中,super.toString 调用父类 Ball 的 toString 方法输出类 Ball 中声明的属性值。 public c
14、lass Point private double xCoordinate; private double yCoordinate; public Point 0 public Point(ouble x, double y) xCoordinate = x; yCoordinate = y; public String toString() return “( + Double.toString(Coordinate)+ “,“ + Double.toString(Coordinate) + “); /other methods public class Ball U (1) /U; /中心
15、点 private double radius; /半径 private String colour; /颜色 public Ball() public Ball(double xValue, double yValue, double r)/ 具有中心点及半径的构造方法 center= U(2) /U;/调用类 Point 中的构造方法 radius = r; public Ball(double xValue, double yValue, double r, String c) / 具有中心点、半径及颜色的构造方法 U (3) /U;/调用 3个参数的构造方法 colour = c; p
16、ublic String toString() return “A ball with center“ + center, toString() + “, radius“ + Double.toString(radius) + “, colour“ + colour; /other methods public class MovingBall. U(4) /U private double speed; public MovingBall() public MovingBall(double xValue, double yValue, double r, String e, double
17、s) U (5) /U;/ 调用父类 Ball 中具有 4 个参数的构造方法 speed = s; public String toString( ) return super, toString( ) + “, speed “+ Double.toString(speed); /other methods public class Tester public static void main(String args) MovingBall mb = new MovingBall(10,20,40,“green“,25); System.out.println(mb); (分数:15.00)_
18、中级软件设计师下午试题-11 答案解析(总分:90.00,做题时间:90 分钟)一、B试题一/B(总题数:1,分数:15.00)1. 【说明】 流程图描述了某宽带数据专线管理系统的部分处理流程。 (1)凡申请宽带数据专线使用者,均需填写专线申请表。系统把申请表存储在专线申请登记文件中,等待分配专线号。 (2)系统为申请者指定专线号,并根据通信距离(按地区计算)、通信计算初装费和月租费,然后发初装通知单送给用户,并产生施工单交有关部门施工。同时产生专线处理文件。专线号是专线的唯一标识。 (3)施工结束后,系统更新用户文件,并产生专线计费文件,作为以后收费的依据。 (4)一个用户可以租用多条专线,
19、用户可用现金或银行托付两种方式支付租金,但一个用户只能使用一种付款方式。系统每月按用户(而不是专线)为单位计费出账。 (5)流程图中各数据文件及有关单据所含的数据项如下。 专线申请表及专线中请登记文件:申请号、用户名称、付款方式,开户银行代码、账号、主端名称、主端地址、对端地址、对端所在地区、通信速率、设备接口、申请日期。 专线处理文件; 申请号、专线号、用户名称、付款方式、开户银行代码、账号、初装费、月租费、完工日期。 初装费收据: 专线号、初装费、交费日期。 施工单: 施工单号、专线号、主端名称、主端地址、对端所在地区,通信速率、设备接口、完工期限。 完工单: 施工单号、专线号、完工日期。
20、 用户文件: 用户编号、用户名称、付款方式、开户银行代码、账号。 专线计费文件: 专线号、用户编号、月租金、开通日期。 【问题 1】 宽带数据专线价目文件由哪些数据项组成? 【问题 2】 为了避免在用户尚未支付初装费时就去施工,有人提议将图中从处理 2 产生的施工单改成从处理 3 产生施工单。试问从处理 3 能否产生施工单?为什么? 【问题 3】 当一个用户使用多条专线时,若允许该用户对其中的一些专线采用现金支付,对另一些专线采用银行托付方式,则在尽量减少数据冗余的前提下,应如何调整有关的数据文件。 (分数:15.00)_正确答案:()解析:问题 1 对端所在区、通信速率、初装费、月租费 问题
21、 2 不能,因为处理 3 的输入文件及单据中缺少施工单中所需的主端名称、主端地址、对端地址、对端所在地区、通信速率、设备接口等数据项。 问题 3 在专线计费文件中加上付款方式数据项,取消用户文件中的付款方式数据项。 解析 专线价目文件只在处理 2 为专线登记文件提供数据项,可能影响到处理 2 输出的初装单通知、施工单和专线处理文件。初装单通知在说明中没有提到,不予考虑。检查施工单和专线处理文件的数据项,可发现初装费、月租费没有出处,所以它们应由专线价目文件提供。同时,专线价目文件与专线申请登记文件配套时,应有一个共同的数据项用以关联,综合考虑,这个数据项应该是帮助选择初装费、门租费,根据常识,
22、应该是对端所在地区(决定初装费)、通信速率(决定月租费)。 对于问题 2,首先看处理 3 的输入数据源,它们是专线处理文件和初装费收据,它们的数据项不能完全生成施工单。 如果要满足问题 3 的要求,取消限制,允许租用多条专线的用户对具体的专线采用不同的付款方式,那么付款方式就不再是某个用户的属性,而是某条专线的属性。所以,应该在专线计费文件中加上付款方式数据项,取消用户文件中的付款力式数据项。二、B试题二/B(总题数:1,分数:15.00)2.【说明】 供应商零件工程项目数据库由以下 4 个关系模式构成: S(SNO,SNAME,STATUS,CITY) P(PNO,PNAME,COLOR,W
23、EIGHT,CITY) J(JNO,TNAME,CITY) SPJ(SNO,PNO,JNO,QTY) 其中,供应商S,零件 P 和工程项目 J 分别由供应商号(SNO),零件号(PNO)和工程项目号(JNO)唯一标识。供货 SPJ 是指由某个供应商向某个工程项目供应某些数量的某种零件。 【问题 1】 请用 SQL 语言完成如下的操作。 找出给北京的工程项目提供不同的零件号: 将没有供货的所有工程项目从 J 中删除; 查询这样的工程项目号:供给该工程项目的零件 P1 的平均供应量大于供给工程项目 n 的任何一种零件的最大供应量。【问题 2】 定义一个视图,它由所有这样的工程项目(工程项目号与所在
24、城市名称)组成:它们由供应商S1 供货且使用零件 P1。(分数:15.00)_正确答案:()解析:问题 1 SELECTDISTlNCT SPJPNO FROM SPJ,J WHERE SPJJNO=JJNO AND JCITY北京 DELETE FROM J WHERE JNO NOT IN ( SELECT JNO FROM SPJ); SELECT DISTINCT JNO FROM SPJ WHERE PNO=P1 GROUP BY JNO HAVING AVG (QTS) (SELECT MAX (QTY) FROM SPJ WHERE JNOJ1); 问题 2 CREATE VIE
25、W J_S1_P1 AS SELECT J.JNO,J.CITY FROM SPJ,J WHERE SPJ.JNO=J.JNO AND SPJ.SNO=S1 AND SPJ.PNO=P1 解析 “找出给北京的工程项目提供不同的零件号”需要两个表(工程项目 J 和供货 SPJ)的联合查找,要使用 DISTINCT 来消除重复项。 “将没有供货的所有工程项目从 J 中删除”,首先要在于查向内从供货(SPJ)表内将所有供货的工程项目号(JNO)查山,然后使用 NOTIN 在工程项目表(J)内将不含有这些 JNO 的记录删除。 问题 1 中这个查询需要使用条件语句 having,还需要使用数学函数 A
26、VG、MAX。 考生还要熟悉视图、索引的语句,请参考有关教材,这里不做说明。三、B试题三/B(总题数:1,分数:15.00)3.【说明】 “进货库存信息管理系统”是 ERP 系统中一个重要的子系统,下面是该系统的一个简化了的主结构功能图。 其中一些各系统功能描述如下: 进货信息管理系统 进货单据建立文件维护管理工作。 进货查询统计管理工作。 进货过账工作。 在进货管理系统中,要处理“成本计算和费用摊消” 的问题。处理方式如下所述。 进口货物的成本计算: (1)先算出本次进货货物的原币总成本金额。 (2)再依照当时原币(如:美金 US$,英镑、港币 HK$等)的汇率乘以本次进货原币总成本金额,算
27、出本次进货台币总成本金额。 (3)再计算出本次进货所产生的全部费用总金额(包含:关税、报关费、运费、其他费用等费用)。 (4)将“本次进货台币总成本金额”加上“全部费用总金额”算出本次实际的“总成本金额”。 (5)再利用下述公式算出各单项货物的“单项货物的成本金额”。 (6)最后一个步骤,再将“单项货物的成本金额”除以单项货物本次进货的数量,即可算出“单一货物本次进货实际的成本金额”。 (分数:15.00)_正确答案:()解析:问题 1 类 1 是抽象类“单一货物成本计算”,类 2 是继承类“进口货物成本计算”。 问题 2 类、接口、关系(合作、依赖、泛化、关联)、限制和批注 问题 3 依赖(
28、Dependency):依赖关系显示一个模型元素需要另一个模型元素来达到某种目的,即一个事物(独立事物)发生变化会影响另一个事物(依赖事物)的语义。程序中的引用(Import)就是一种依赖关系。 泛化(Generalization);描述的是两组某些方面具有共性的事务之间存在的一种关系。父类到子类的继承就是一种泛化。 解析 题中描述的是进口货物成本计算的方式,要求使用抽象和继承来设计类,根据面向对象设计方法和题意可以得到:应建立一个抽象类“甲一货物成本计算”,而“进口货物成本计算”类则继承并实现这个抽象类。 所以,根据图示中泛化的表示方向,类 1 是抽象类“单一货物成本计算”,类 2 是继承类
29、“进口货物成本计算”。 类图根据系统中的类,以及各个类之间的关系描述系统的静态视图。 类图的结构,简单的分析一般包括下列的事物和组件: 类(CLASS) 接口(Interface) 合作(Collaboration) 依赖(Dependency) 泛化(Generalization) 关联(Association) 限制和批注四、B试题四/B(总题数:1,分数:15.00)4.【说明】 函数 DeleteNode (Bitree *r, int e)的功能是:在树根结点指针为 r 的二叉查找(排序)树上删除键值为 e 的结点,若删除成功,则函数返回 0,否则函数返回-1。二叉查找树结点的类型定
30、义为: typedef struct Tnode int data; /*结点的键值*/ struct Tnode *Lchild, *Rchild; /*指向左、右子树的指针*/ *Bitree: 在二叉查找树上删除一个结点时,要考虑 3 种情况: 若待删除的结点 p 是叶子结点,则直接删除该结点; 若待删除的结点 p 只有一个子结点,则将这个子结点与待删除结点的父结点直接连接,然后删除结点 p; 若待删除的结点 p 有两个子结点,则在其左子树上,用中序遍历寻找关键值最大的结点 s,用结点 s 的值代替结点 p 的值,然后删除结点 s,结点 s 必属于上述、情况之一。 【函数】 int De
31、leteNode (Bitree *r,int e) Bitree p=*r,pp,s,c; while (U (1) /U) /*从树根结点出发查找键值为 e 的结点*/ pp=p; if(ep-data) p=p-Lchild; else p=p-Rchild; if(!P) return-1; /*查找失败*/ if(p-Lchild p-data=s-data; p=s; /*处理情况、*/ if U(U (4) /U) /Uc=p-Lchild; else c=p-Rchild; if(p=*r) *r=c; else if U(U (5) /U) /Upp-Lchild=c; el
32、se pp-Rchild=c; free (p); return 0; (分数:15.00)_正确答案:()解析:解析 (1)p template class T class ArrayBody friend U (1) /U T* tpBody; int iRows, iColumns, iCurrentRow; ArrayBody (int iRsz, int iCsz) tpBody = U(2) /U iRows = iRsz; iColumns =iCsz; iCurrentRow =-1; public: T row_error=column_error=false; try if
33、 (iCurrentRow 0 | iCurrentRow =iRows) row_error=true; if (j 0 | j =iColumns) column_error=true; if ( row_error=true | column_error = true) U (3) /U catch (char) if (row_error=true) cerr “行下标越界“ iCurrentRow “ “; if (column_error= true ) cerr “列下标越界“ j “; cout “/n“; return tpBodyiCurrentRow * iColumns
34、 +j; ; ArrayBody ( ) delete tpBody; ; template class T class Array ArrayBodyT tBody; public: ArrayBodyT Array (int iRsz, int iCsz) : U(5) /U ; void main() Arrayinta1(10,20); Arraydoublea2(3,5); int b1; double b2; b1=a1-510; /有越界提示:行下标越界-5 b1=a11015; /有越界提示:行下标越界10 b1=a114; /没有越界提示 b2=a226; /有越界提示:列下
35、标越界6 b2=s21020; /有越界提示:行下标越界10列下标越界20 b2=a214; /没有越界提示 (分数:15.00)_正确答案:()解析:解析 (1)class ArrayT (2)new TiRsz*iCsz (3)throw e (注:throw 后可以填写任意的字符常数) (4)tBody.iCurrentRow=i (5)tBody (iRsz,iCsz) 分析:(1)的前面是友元关键词 friend,但在程序中,没有独立的函数,所以只能是另一个模板类 Array,所以(1)应填写 class ArrayT。 在类模板 ArrayBody 的定义中,声明了成员变量 T t
36、pBody,且在析构函数中有 delete tpBody,由于在C+中,delete 总是和 new 成对出现的,所以(2)应该使用 new 对 tpBody 进行初始化。通过程序中 return tpBodyiCurrentRow * iColumns+j行,可以发现该题中采用的是以一维数组来模拟二维数组的创建。在构造函数有两个参数,分别为行数和列数所以(2)应填写 new TiRsz * iCsz。 (3)的前后有 try和 catch语句序列,这是 C 料中典型的异常处理搭配语句。由于(3)前面已作处理,当有行下标越界时,置 row error=true;当有列下标越界时,置 col e
37、rror=true。且(3)前面的判断是“row error=true|column errortrue”,也就是说只要有行下标越界或是列下标越界就执行(3)。错误处理语句写好放在 catch 中,catch 是当正常程序段发生异常时才执行的,并且这里指明了是 catch(char),所以只要在(3)抛出一个 char 异常,即可进行错误处理。所以(3)应填:throw e(这里可以是任何字符)。再来看 Array 类中的两个空。首先看(5),这显然是做一些初始化工作,给其成员变量赋初值,而 Array类只有一个成员变量 tBody,且 tBody 是 ArrayBody 类型的,ArrayB
38、ody 的构造函数需要传递两个参数,分别代表数组的行和列。因此,(5)应填写 tBody (iRsz, iCsz)。 main 中实例化 Array,而在类 Array的构造函数对 tBody 这个变量进行实例化,这时就以一维数组的形式创建了二维数组。在类 Array 中口运算符重载函数中返回了一个 ArrayBody 类,而在 ArrayBody 也存在着运算符重载函数,并且在ArrayBody 的重载函数中对行下标和列下标同时进行了检查,且返回了一个 T 类型,对 Arrayint来说就是返回了 int,也就是数组的一个元素。那么通过对类 ArrayBody 的观察,发现在整个 Array
39、Body 中并没有任何地方对 iCurrentRow 进行赋值,而在 ArrayBody 的运算符重载中却利用其对数组行下标进行判断,而数组的行下标只在 Array 的口运算符重载中出现,那么 (4)就应该是对类 ArrayBody 的成员变量iCurrentRow 进行赋值,所以(4)应填入 tBody.iCurrentRow=i。六、B试题六/B(总题数:1,分数:15.00)6.【说明】下面的程序先构造 Point 类,再顺序构造 Ball 类。由于在类 Ball 中不能直接存取类 Point 中的 xCoordinate 及 yCoordinate 属性值,Ball 中的 toStri
40、ng 方法调用 Point 类中的 toString 方法输出中心点的值。在 MovingBall 类的 toString 方法中,super.toString 调用父类 Ball 的 toString 方法输出类 Ball 中声明的属性值。 public class Point private double xCoordinate; private double yCoordinate; public Point 0 public Point(ouble x, double y) xCoordinate = x; yCoordinate = y; public String toString
41、() return “( + Double.toString(Coordinate)+ “,“ + Double.toString(Coordinate) + “); /other methods public class Ball U (1) /U; /中心点 private double radius; /半径 private String colour; /颜色 public Ball() public Ball(double xValue, double yValue, double r)/ 具有中心点及半径的构造方法 center= U(2) /U;/调用类 Point 中的构造方法
42、 radius = r; public Ball(double xValue, double yValue, double r, String c) / 具有中心点、半径及颜色的构造方法 U (3) /U;/调用 3个参数的构造方法 colour = c; public String toString() return “A ball with center“ + center, toString() + “, radius“ + Double.toString(radius) + “, colour“ + colour; /other methods public class MovingB
43、all. U(4) /U private double speed; public MovingBall() public MovingBall(double xValue, double yValue, double r, String e, double s) U (5) /U;/ 调用父类 Ball 中具有 4 个参数的构造方法 speed = s; public String toString( ) return super, toString( ) + “, speed “+ Double.toString(speed); /other methods public class Tester public static void main(String args) MovingBall mb = new MovingBall(10,20,40,“green“,25); System.out.println(mb); (分数:15.00)_正确答案:()解析:解析 (1)private