问答题【说明】现要编写一个画矩形的程序,目前有两个画图程序:DP1和DP2,DP1用函数draw_a_line(x1,y1,x2,y2)画一条直线,DP2则用drawline(x1,x2,y1,y2)画一条直线。当实例画矩形时,确定使用DP1还是DP2。为了适应变化,包括“不同类型的形状”和“不同类型的画图程序”,将抽象部分与实现部分分离,使它们可以独立地变化。这里,“抽象部分”对应“形状”,“实现部分”对应“画图”,与一般的接口(抽象方法)与具体实现不同。这种应用称为Bridge(桥接)模式。图9-6显示了各个类间的关系。这样,系统始终只处理3个对象:Shape对象、Drawing对象、DP1或DP2对象。以下是Java语言实现,能够正确编译通过。【Java代码】//DP1.java文件publicclassDP1staticpublicvoiddraw_aline(doublex1,doubley1,doublex2,doubley2)//省略具体实现//DP2.java文件publicclassDP2staticpublicvoiddrawline(doublex1,doubley1,doublex2,doubley2)//省略具体实现//Drawing.java文件(1)publicclassDrawingabstractpublicvoiddrawLine(doublex1,doubley1,doublex2,doubley2);//V1Drawing.java文件publicclassV1DrawingextendsDrawingpublicvoiddrawLine(doublex1,doubley1,doublex2,doubley2)DP1.draw_a_line(x1,y1,x2,y2);//V2Drawing.java文件publicclassV2DrawingextendsDrawingpublicvoiddrawLine(doublex1,doubley1,doublex2,doubley2)(//画一条直线(2);//Shape.java文件abstractpublicclassShapeabstractpublicvoiddraw();private(3)_dp;Shape(Drawingdp)_dp=dp;protectedvoiddrawLine(doublex1,doubley1,doublex2,doubley2)(4);//Rectangle.java文件publicclassRectangleextendsShapeprivatedouble_x1,_x2,_y1,_y2;publicRectangle(Drawingdp,doublex1,doubley1,doublex2,doubley2) (5);_x1=x1;_x2=x2;_y1=y1;_y2=y2;publicvoiddraw()//省略具体实现
问答题阅读以下说明和图,根据要求回答下列问题。[说明]某音像制品出租商店欲开发一个音像管理信息系统,管理音像制品的租借业务。需求如下。1.系统中的客户信息文件保存了该商店的所有客户的用户名、密码等信息。对于首次来租借的客户,系统会为其生成用户名和初始密码。2.系统中音像制品信息文件记录了商店中所有音像制品的详细信息及其库存数量。3.根据客户所租借的音像制品的品种,会按天收取相应的费用。音像制品的最长租借周期为1周,每位客户每次最多只能租借6件音像制品。4.客户租借某种音像制品的具体流程如下。(1)根据客户提供的用户名和密码,验证客户身份。(2)若该客户是合法客户,查询音像制品信息文件,查看商店中是否还有这种音像制品。(3)若还有该音像制品,且客户所要租借的音像制品数小于等于6个,就可以将该音像制品租借给客户。这时,系统给出相应的租借确认信息,生成一条新的租借记录并将其保存在租借记录文件中。(4)系统计算租借费用,将费用信息保存在租借记录文件中并告知客户。(5)客户付清租借费用之后,系统接收客户付款信息,将音像制品租借给该客户。5.当库存中某音像制品数量不能满足客户的租借请求数量时,系统可以接受客户网上预约租借某种音像制品。系统接收到预约请求后,检查库存信息,验证用户身份,创建相应的预约记录,生成预约流水号给该客户,并将信息保存在预约记录文件中。6.客户归还到期的音像制品,系统修改租借记录文件,并查询预约记录文件和客户信息文件,判定是否有客户预约了这些音像制品。若有,则生成预约提示信息,通知系统履行预约服务,系统查询客户信息文件和预约记录文件,通知相关客户前来租借音像制品。现采用结构化方法对音像管理信息系统进行分析与设计,获得如图7-9所示的顶层数据流图和图7-10所示的0层数据流图。
问答题【说明】已知某类库开发商捉供了一套类库,类库中定义了Application类和Document类,它们之间的关系如下图所示,其中,Application类表示应用程序自身,而Document类则表示应用程序打开的文档。Application类负责打开一个已有的以外部形式存储的文档,如一个文件,一旦从该文件中读出信息后,它就由一个Document对象表示。当开发一个具体的应用程序时,开发者需要分别创建自己的Application和Document子类,例如上图中的类MyApplication和类MyDocument,并分别实现Application和Document类中的某些方法。已知Application类中的openDocument方法采用了模板方法(TemplateMethod)设计模式,该方法定义了打开文档的每一个主要步骤,如下所示:1.首先检查文档是否能够被打开,若不能打开,则给出出错信息并返回;2.创建文档对象;3.通过文档对象打开文档;4.通过文档对象读取文档信息;5.将文档对象加入到Application的文档对象集合中。【Java代码】abstractclassDocument{ publicvoidsave(){/*存储文档数据,此处代码省略*/) publicvoidopen(StringdocName){/*打开文档,此处代码省略*/) publicvoidclose(){/*关闭文档,此处代码省略*/) publicabstractvoidread(StringdocName);};abstractclassAppplication{ privateVector<{{U}}(1){{/U}}>docs;/*文档对象集合*/ publicbooleancanOpenDocument(StringdocName){ /*判断是否可以打开指定文档,返回真值时表示可以打开, 返回假值表示不可打开,此处代码省略*/ } publicvoidaddDocument(DocumentaDocument){ /*将文档对象添加到文档对象集合中*/ docs.add({{U}}(2){{/U}}); } publicabstractDocumentdoCreateDocument();/*创建一个文档对象*/ publicvoidopenDocument(StringdocName){/*打开文档*/ if({{U}}(3){{/U}}){ System.out.println(“文档无法打开!”); return; } {{U}}(4){{/U}}adoc={{U}}(5){{/U}}; {{U}}(6){{/U}}; {{U}}(7){{/U}}; {{U}}(8){{/U}}; }};
问答题【说明】用克鲁斯卡尔算法求解给定图的最小生成树。
#include <stdio. h>
#include <stdlib. h>
#define MAXN 30
typedef struct
{ int v1,v2; /*一条边依附的两个顶点*/
int weight; /*边上的权值*/
}EDGE;
typedef struct
{ int Vnum; /*图中的顶点数目*/
EDGE e[MAXN*(MAXN-1)/2]; /*图中的边*/
}Graph;
typedef struct node{ /*用链表存储同一个连通分量的顶点*/
int v;
struct node *next;
}Alist;
void heapadjust(EDGE data[], int s, int m)
{ /*将元素序列data[s..m]调整为小顶堆, 堆顶元素(最小元素)为data[s]*/
int j;
EDGE t;
t=data[s]; /*备份元素data[s], 为其找到适当位置后再插入*/
for(j=2*s+1; j<=m; j=j*2+1){/*沿值较小的子结点向下筛选*/
if(j<m
if(!(t. weight>data[j]. weight)) break;
data[s]=data[j];s=j; /*用s记录待插入元素的位置(下标)*/
}/*for*/
data[s]=t; /*将备份元素插入由s所指出的插入位置*/
}/*heapadjust*/
int creat_graph(Graph *p) /*输入图中的顶点及边, 返回图中边的数目*/
{ int k=0; /*记录图中边的数目*/
int n;
int v1,v2;
int w;
printf("vertex number of the graph:");
scanf("%d", /*输入图中的顶点数目*/
if(n<1) return 0;
p->Vnum=n;
do{ printf("edge(vertex1,vertex2,weight):");
scanf("%d %d %d",
if(v1>=0 p->e[k]. v2=v2; p->e[k]. weight=w;
k++;
}/*if*/
}while(!({{U}} (2) {{/U}}));
return k; /*返回图中边的数目*/
}/*creat_graph*/
int kruskal(Graph G, int enumber, int tree[][3])
{ /*用kruskal算法求无向连通图G的最小生成树, 图中边所得数目为enumber, */
/*数组tree[][3]中存放生成树中边的顶点和边上的权值, 函数返回生成树的代价*/
int i, k, m, c=0;
int v1, v2;
Alist *p, *q, *a[MAXN];
for(i=0; i<G.Vnum; ++i){ /*将每个连通分量中的顶点存放在一个单链表中*/
a[i]=(Alist*)malloc(sizeof(Alist));
if(!a[i]) {
printf("/n mernory allocation error!");
exit(0);
}/*if*/
a[i]->v=i; a[i]->next=NULL;
}/*for*/
for(i=enumber-1; i>=0; --i)/*按照边上的权值建立小顶堆*/
heapadjust({{U}} (3) {{/U}});
k=G. Vnum; /*k用于计算图中的连通分量数目*/
m=enumber-1;
i=0;
do{
v1=G. e[0]. v1; v2=G. e[0]. v2;
p=a[v1];
while(p p=p->next;
}
if(!p){ /*当前边的顶点不在一个连通分量中*/
p=q;
p->next=a[G. e[0]. v2];
p=a[G. e[0]. v1); /*加入边(v1,v2), 将两个连通分量合并为一个*/
while(p){a[p->v]={{U}} (4) {{/U}}; p=p->next; }
k--; /*连通分量数目减少一个*/
tree[i][0]=v1; /*记录加入最小生成树的边*/
tree[i][1]=v2;
tree[i][2]=G. e[0]. weight;
c+=G. e[0]. weight;
++i;
}/*if*/
G. e[0]=G. e[m];
m--;
heapadjust ({{U}} (5) {{/U}});
} while(k>1); /*当所有顶点不在同一个连通时, 继续*/
return c; /*返回最小生成树的代价*/
} /*kruskal*/
void main(void)
{ int i, enumber;
int tree[MAXN][3];
int cost=0;
Graph G;
enumber=creat_graph(
cost=-kruskal(G,enumber,tree);
printf("Minimum-Cost spanning tree(kruskal):/n");
printf("edge/t weight/t/n");
for(i=0; i<G. Vnum-1; ++i)
printf("v %d –v %d /t %d/n", tree[i][0], tree[i][1], tree[i][2]);
printf("Cost:%d/n", cost);
}
问答题[说明]对于数学上一个猜想:任何自然数平方的36倍等于两对孪生素数的和。初始的情形如下:12×36=(5+7)+(11+13)22×36=(29+31)+(41+43)32×36=(11+13)+(149+151)再往下,N取4,5,6,时,只要N不太大,也都可以找到N(上标)2×36等于两对孪生素数的和。但是当N是一个任意的正整数时,证明N2×36总是等于两对孪生素数的和,这还是一个目前尚未解决的问题。甚至当考察的数较大时,找出一组符合条件的两对孪生素数都是计算量相当大的工作。每尝试一次,都要作4次是否是素数的判断,要作许多次的尝试,才可能找到一组解。下面流程图设计了一种优化算法来对这个猜想进行验证。仔细阅读流程图8-11,完成程序部分。图8-11[程序部分]main(){intt,i,j,prime_index;is_prime:longn,p,p1,p2,p3,p4,s,s1;longprimes[16000];for(n=1;n<98;++n){t=0;s=n*n*36;prime_index=2;primes[0]=2;primes[1]=3;for(p=5:p<=s/2;p=p+2){is_prime=1;for(i=1;{{U}}(1){{/U}}++i)if(p%primes[i]==0)is_prime=0;if(is_prime){{{U}}(2){{/U}}}}for(i=1;{{U}}(3){{/U}}++i){{{U}}(4){{/U}}if(p2=p1+2){s1=s-(p1+p2)p3=sl/2-1;p4=p3+2:for(j=0;j<=prime_index-1;++j)if({{U}}(5){{/U}}){printf("%d*%d*36=(%d+%d)+(%d+%d)/n",/n,n,p1,p2,p3,p4);++t;}}}if(t!=0)printf("%d/n",t)elseprintf("%d*%d*36=nosolution/n",n,n);}}}
问答题【说明】函数int Toplogical(LinkedWDigraph G)的功能是对图G中的顶点进行拓扑排序,并返回关键路径的长度。其中图G表示一个具有n个顶点的AOE一网,图中顶点从1~n依次编号,图G的存储结构采用邻接表表示,其数据类型定义如下:
typedef struct Gnode{ /*邻接表的表结点类型*/
int adivex; /*邻接顶点编号*/
int weight; /*弧上的权值*/
bstmct Gonde*nextare; /*指示下一个弧的结点*/
}Gnode;
typedef struct Adjlist{ /*邻接表的头结点类型*/
char vdata; /*顶点的数据信息*/
struct Gnode*Firstadj; /*指向邻接表的第1个表结点*/
}Adjlist;
typedef struct LinkedWDigraph{ /*图的类型*/
int n, e; /*图中顶点个数和边数*/
struct Adjlist head; /*指向图中第1个顶点的邻接表的头结点*/
}LinkedWDigraph;
【函数】
int Toplogical(LinkedWDigraph G)
{ Gnode *p;
int j,w,top=0;
int *Stack,*ve,*indegree;
ve=(int *)mallloc(G.n+1)* sizeof(int)};
indegree=(int *)malloc((G.n+1)*sizeof(int));/*存储网中个顶点的入度*/
Stack=(int *)malloc((G.n+1)*sizeof(int)); /*存储入度为0的顶点的编号*/
if(!ve‖!indegree‖!Stack)
exit(0);
for(j=1;j<=G.n;j++){
ve[j]=0; indegree[j]=0;
}/*for*/
for(j=1;j<=G.n;j++){ /*求网中各顶点的入度*/
p=G.head[j].Firstadj;
while(p){
{{U}}(1) {{/U}}; p=p->nextarc;
}/*while*/
}/*for*/
for(i=1;j<=G.n;j++) /求网中入度为0的顶点并保存其编号*/
if(!indegree[j]) Stack[++top]=j;
while(top>0){
w={{U}} (2) {{/U}};
printf("%c", G.head[w].vdata);
p=G.head[w].Firstadj;
while(p){
{{U}} (3) {{/U}};
if(!indegree[p->adjvex])
Stack[++top]=p->adjvex;
if({{U}} (4) {{/U}})
ve[p->adjvex]=ve[w]+p->weight;
p=p->nextarc;
}/*while*/
return{{U}} (5) {{/U}};
}/*Toplogical*/
问答题【问题3】
打印分户账清单时,必须以下列哪一组数据作为关键字进行排序,才能满足需求?请从下面选项中选择。
①储蓄所 ②账号 ⑧开户日 ④总户数和总余额
问答题[说明] 任何一种程序都是为了解决问题而撰写的,解决问题时需要实现一些特定的运算法则。在策略(Strategy)模式下,可以更换实现算法的部分而不留痕迹,切换整个算法,简化改为采用其他方法来解决同样问题。 以下是一个“剪刀石头布”游戏。猜拳时的“策略”有2种方法:第一种是“猜赢后继续出同样的招式”(WinningStrategy),第二种是“从上一次出的招式种,以概率分配方式求出下一个招式的几率”(ProbStrategy)。程序中定义了Hand类表示猜拳时的“手势”,类内部以0(石头)、1(剪刀)、2(布)来表示。Hand类的实例只会产生3个。 以下是Java语言实现,省略了不相关属性及方法,方法实现体亦有所省略,能够正确编译通过。 [Java代码] //Hand.java文件 public class Hand public static final int HANDVALUE_GUU = 0; //石头 public static final int HANDVALUE_CHO = 1; //剪刀 public static final int HANDVALUE_PAA = 2; //布 public static final Hand[] hand = new Hand(HANDVALUE_GUU), new Hand(HANDVALUE_CHO), new Hand(HANDVALUE_PAA), ; private int handvalue; (1) Hand(int handvalue) this.handvalue = handvalue; public (2) Hand getHand(int handvalue)(//从值取得对象实例 return hand[handvalue]; //Strategy.java文件 public interface Strategy public (3) Hand nextHand(); //ProbStrategy.java文件 import java.util.Random; public class ProbStrategy implements Strategy public Hand nextHand() int handvalue = 0; /*省略具体实现*/ return Hand.getHand(handvalue); //WinningStrategy.java文件 import java.util.Random; public class WinningStrategy implements Strategy /*省略了不相关属性*/ public Hand nextHand() if(!won) prevHand = Hand.getHand(random.nextInt(3)); return prevHand; //Player.java文件 public class Player private String name; private Strategy strategy; public Player(String name, (4) strategy) this.name = name; this.strategy = strategy; public Hand nextHand()//向战略请示手势 return (5) ;
问答题阅读下列函数说明,将应填入 (n) 处的字句写在答卷纸的对应栏内。 【函数1说明】 函数compare(SqList A,SqList B)的功能是:设A=(al,…,am)和B=(b1,…,bn)均为顺序表,“比较”两个顺序表A和B的大小。设A'和B'分别为A和B中除去最大共同前缀后的子表(例如,A=(y,X,X,Z,X,Z),B=(y,x,x,z,y,x,x,2),则两者中最大的共同前缀为(y,x,x,2),在两表中除去最大共同前缀后的子表分别为A'=(X,Z)和B'=(y,x,x,2))。若A'=B'=空表,则 A=B:若A'=空表,而B'≠空表,或者两者均不为空表,且A'的首元小于B,的首元,则A<B;否则A>B。 提示:算法的基本思想为:若相等,则j+1,之后继续比较后继元素:否则即可得山比较结果。显然,j的初值应为0,循环的条件是j不超出其中任何一个表的范围。若在循环内不能得出比较结果,则循环结束时有3种可能出现的情况需要区分。 【函数1】 int compare(SqList A,SqList B) //若A<B,则返回-1;若A=B,则返回o:若A>B,则返回1 j=0; while(j< (1) else if( A.elem[j] > B.elem[j] ) return(i); else (2) ff (A.length == B.length) return (0); else fi(A.length < B.length ) return(-1); else return(1); //compare //函数1的时间复杂度是 (3) 【函数2说明】 函数 exchange_L( SLink k = 1; while( k< m ++k; if( (6) // 以指针ha记a1 结点的位置 L->next = p->next; // 将b1结点链接在头结点之后 p->next = NULL; // 设am的后继为空 q: (7) ; // 令q 指向b1结点 while(q->next)q= (8) ; // 查的bn结点 q->next = (9) ; // 将a1 结点链接到bn 结点之后 //函数2的时间复杂度是 (10) 。
问答题【说明】清点盒子。本程序当用户输入一个整数值时,一切正常;当输入其他数值时,程序就出错。现在已做了改进,请填空。import java. text. NumberFormat;Public class InventoryLoop public static void main(String args[]) String numBoxesIn; Int numBoxes; Double boxPrice=3.25; Boolean gotGoodInput=false; NumberFormat currency=NumberFormat. (1) ; do System.out. print(“How many boxes do we have?”); numBoxesIn=DummiesIO. (2) ; try numBoxes=Integer.parseInt( (3) ); system. out. print("The value is"); system.out. println(currency, format (numBoxes*boxPrice)); gotGoodInput=true; catch( (4) ) System.out.println(); System.out. println(That's not a number."); while( (5) );//输入不正确时 System. out.println("That's that.");
问答题[说明]某高校欲开发一个成绩管理系统,记录并管理所有选修课程的学生的平时成绩和考试成绩,其主要功能描述如下。(1)每门课程都由3~6个单元构成,每个单元结束后会进行一次测试,其成绩作为这门课程的平时成绩。课程结束后进行期末考试,其成绩作为这门课程的考试成绩。(2)学生的平时成绩和考试成绩均由每门课程的主讲教师上传给成绩管理系统。(3)在记录学生成绩之前,系统需要验证这些成绩是否有效。首先,根据学生信息文件来确认该学生是否选修这门课程,若没有,那么这些成绩是无效的;如果学生的确选修了这门课程,再根据课程信息文件和课程单元信息文件来验证平时成绩是否与这门课程所包含的单元相对应,如果是,那么这些成绩是有效的,否则无效。(4)对于有效成绩,系统将其保存在课程成绩文件中。对于无效成绩,系统会单独将其保存在无效成绩文件中,并将详细情况提交给教务处。在教务处没有给出具体处理意见之前,系统不会处理这些成绩。(5)若一门课程的所有有效的平时成绩和考试成绩都已经被系统记录,系统会发送课程完成通知给教务处,告知该门课程的成绩已经齐全。教务处根据需要,请求系统生成相应的成绩列表,用来提交考试委员会审查。(6)在生成成绩列表之前,系统会生成一份成绩报告给主讲教师,以便核对是否存在错误。主讲教师须将核对之后的成绩报告返还系统。(7)根据主讲教师核对后的成绩报告,系统生成相应的成绩列表,递交考试委员会进行审查。考试委员会在审查之后,上交一份成绩审查结果给系统。对于所有通过审查的成绩,系统将会生成最终的成绩单,并通知每个选课学生。现采用结构化方法对这个系统进行分析与设计,得到如图1所示的顶层数据流图和如图2所示的0层数据流图。
问答题阅读下列说明,根据要求回答下列问题。[说明]某医院的门诊管理系统实现了为患者提供挂号、处方药品收费的功能。具体的需求及设计如下。1.医院医师具有编号、姓名、科室、职称、出诊类型和出诊费用,其中出诊类型分为专家门诊和普通门诊,与医师职称无关;各个医师可以具有不同的出诊费用,与职称和出诊类型无关。2.患者首先在门诊挂号处挂号,选择科室和医师,根据选择的医师缴纳挂号费(医师出诊费)。收银员为患者生成挂号单,如表7-15所示,其中,就诊类型为医师的出诊类型。表7-15 ××医院门诊挂号单 收银员:13011 时间:2007年2月1日08:58就诊号姓名科室医师就诊类型挂号费20070205015叶萌内科杨玉明专家门诊5元3.患者在医师处就诊后,凭借挂号单和医师手写处方到门诊药房交费买药。收银员根据就诊号和医师处方中开列的药品信息,查询药品库(见表7-16)并生成门诊处方单(见表7-17)。表7-16 药品库药品编码药名称类型库存货架编号单位规格单价12007牛蒡子中药51590B1401G炒0.034011090百部中药36950B1523G片0.0313表7-17 ××医院门诊处方单 时间:2007年2月1日10:31就诊号20070205015病人姓名叶萌医师姓名杨玉明金额总计0.65项目总计2收银员21081药品编码药品名称数量单位单价金额(元)12007牛蒡子10G0.03400.3411090百部10G0.03130.314.由于药品价格会发生变化,因此门诊管理系统必须记录处方单上药品的单价。[概念模型设计]根据需求阶段收集的信息,设计的实体联系图(不完整)如图7-11所示。[逻辑结构设计]根据概念模型设计阶段完成的实体联系图,得出如下关系模式(不完整)。挂号单(就诊号,病患姓名,医师编号,时间,______)收银员(编号,姓名,级别)医师(编号,姓名,科室,职称,出诊类型,出诊费用)门诊处方(______,收银员,时间)处方明细(就诊号,______)药品库(药品编码,药品名称,______)
问答题【说明】某超市的销售业务由一个销售业务管理系统进行管理,该系统每完成一次交易都需要提供顾客发票,其格式如表1-1所示。对于这样一个销售业务管理系统,分别给出了以下两种关系数据库的设计(下划线表示主关键字)设计一:顾客Customer(顾客代码Cno,姓名name,住址address,联系电话phone)收银员Salesman(收银员代码Sno,身份证号idno,姓名flame,住址address,联系电话phone)商品Merchandise(商品代码Milo,商品名称Mname,价格price)发票Invoice(发票号码Ino,交易日期Idate,顾客代码Cno,收银员代码Sno,商品代码Mno,单价unitprice,数量amount)设计二:顾客Customer(顾客代码Cno,姓名name,住址address,联系电话phone)收银员Salesman(收银员代码Sno,身份证号idno,姓名name,住址address,联系电话吵one)商品Merchandise(商品代码Mno,商品名称mllame,价格pnce)发票Invoice(发票号码Ino,交易日期Idate,顾客代码Cno,收银员代码Sno)发票明细Invoicedetail(发票号码Ino,商品代码Uno,单价unitprice,数量amount)1.【问题1】设计一的关系模式Invoice最高满足第几范式?为什么?设计一和设计二哪个更加合理?为什么?
问答题[说明]以下代码实现了对象引用作为函数参数,仔细阅读以下代码,分析运行结果,填入 (n) 处。[代码] #include<iostream.h> class Sample int x,y; public: Sample() x=y=0; Sample (int i, int j ) x=i; y=j; void copy ( Sample y=j; void print ( cout<<"x="<<x<<end1 ; cout <<"y="<<y<<end1; ; void Sample: copy ( Sample y=s.y; void func ( Sample s1, Sample s2.setxy ( 30,40 ); void main ( ) Sample p ( 1,2 ) ,q; q.copy ( p ); time ( p,q ); p.print ( ); q.print ( ); 运行结果 (1) (2) (3) (4)
问答题【说明】 某供销系统接受顾客的订货单,当库存中某配件的数量小于订购量或库存量低于一定数量时,向供应商发出采购单;当某配件的库存量大于或等于定购粮食,或者收到供应商的送货单并更新了库存后,向顾客发出提货单。该系统还可随时向总经理提供销售和库存情况表。该供销系统的分层数据流图中部分数据流和文件的组成如下: 文件 配件库存=配件号+配件名+规格+数量+允许的最低库存量 数据流 订货单=配件号+配件名+规格+数量+顾客名+地址 提货单=订货单+金额 采购单=配件号+配件名+规格+数量+供应商名+地址 送货单=配件号+配件名+规格+数量+金额 假定顶层图(如图6所示)是正确的,“供应商”文件已由其他系统生成。
问答题[说明] 下面代码实现类A、B、C、D的继承定义和应用。仔细阅读[代码5-1],在 (n) 处写出正确的运行结果。 [代码5-1] #include<iostream.h> class A public: int a; A (int v1): a(v1) //构造函数 void disp ( ) cout<<"a in class A="<<a<<endl; ; class B: virtual public A public: int b; B (int v1,int v2): A(v1),b v2) //构造函数 void disp ( ) cout<<"a in class B="<<a<<endl cout<<"b in class B="<<b<<endl; ; class C: virtual public A public: int c; C (int v1,int v2): A(v1) ,c(v2) //构造函数 void disp ( ) cout<<"a in class C="<<a<<endl; cout<<"c in class C="<<c<<endl; ; class D: public B, public C public: int d; D (int v1,int v2,int v3,int v4 ): A(v1) ,B(v1,v2) ,C(v1,v3),d(v4) //构造函数 void disp ( ) cout<<"a="<<a<<endl; cout<<"b="<< b<<endl; cout<<"c="<<c<<endl; cout<<"d="<<d<<endl; ; void main( ) D demo (10,20,30,40); demo.disp ( ); [运行结果] a= (1) b= (2) c= (3) d= (4)
问答题[说明]在数据链路层扩展局域网时使用网桥。网桥工作在数据链路层,它根据MAC帧的目的地址对收到的帧进行转发。网桥具有过滤帧的功能:当网桥收到一个帧时,并不是向所有的端口转发此帧,而是先检查此帧的目的MAC地址,然后确认将该帧转发到哪个端口。最简单的网桥有两个端口(即接口)。网桥的每个端口与一个网段相连。每当收到一个帧时,通过查找转发表将收到的帧转发。当一个网桥刚刚连接到局域网上时,其转发表是空的,此时若收到一个帧,按照以下算法处理和建立自己的转发表:(1)从端口x收到的无差错的帧(如有差错即丢弃),在转发表中查找目的站MAC地址;(2)如有,则查找出到此MAC地址应走的端口d,然后进行(3),否则转到(5);(3)如到这个MAC地址去的端口d=x,则丢弃此帧(因为这表示不需要经网桥进行转发),否则从端口d转发此帧;(4)转到(6);(5)向网桥除x以外的所有端口转发此帧(这样做可以保证找到目的站);(6)如源站不在转发表中,则将源站MAC地址加入转发表,登记该帧进入网桥的端口号,设置计时器,然后转到(8),如源站在转发表中,则执行(7);(7)更新计时器;(8)等待新的数据帧,转到(1)。这时,网桥就在转发表中登记以下三个信息:站地址——登记收到帧的源MAC地址、端口——登记收到的帧进入该网桥的端口号、时间——登记收到的帧进入该网桥的时间。现有五个工作站分别连接在三个局域网上,并且用两个网桥连接起来,如图3-1。每一个网桥的两个端口号都标明在图上。在一开始,两个网桥中的转发表都是空的。以后有以下各站向其他的站发送了数据帧,即H1发送给H5,H3发送给H2,H4发送给H3,H2发送给H1。[图3-1]1.试将有关数据填写在表中。其中,网桥的处理有:转发、丢弃或登记。假定帧均无差错。发送的帧网桥1的转发表网桥2的转发表网桥1的处理网桥2的处理站地址端口站地址端口H1->H5H3->H2H4->H3H2->H1
问答题【程序说明】 本程序先从文件读人各考生的准考证号(设为整型数)及成绩,并将其存放在一棵检索二叉树上,二叉树结点的健值是成绩,每个结点带一链表,链表结点存放取得该成绩的考生的准考证号。然后,程序按中序遍历检索二叉树,从高分到低分输出结果,使每行输出成绩及其取得成绩的考生的准考证号。 【程序】 #include < stdio. h > typedef struet idnode int id; struct idnode * next; ldNode; typedef struct marknode I int mark; ldNode * head; struct marknode * left, * right; MarkNode; char fname [ ] = "sp07.dat"; main( ) int id, mark; MarkNode * root = null; FILE * fp = fopen(fname," r" ); if(!fp) printf("file%s open error, /n" , fname); exit(0); while (!feop(fp)) fscanf(fp," %d%d", btree( fclose(fp); print(root); btree(MarkNod * * mpptr, int id, int mark) ldNode * ip; MarkNode *mp = * mpptr; if (1) if (mark==p->mark) addldNODE ( (2) , id); else if ( mark >mp -> mark) btree ( else btree( else Imp = ( marknode * ) malloc(sizeo (marknode) ); mp -> mark = mark; mp -> left =mp -> right = NULL; (3) addldNode( (4) ; addldNode(ldNode * * ipp, int id) ldNode * ip = * ipp; if ( (5) )addldNode ( (6) ), id; else ip = (ldNode * )malloc(sizeof(ldNode) ); sp - > id = id; ip -> next = NULL; (7) print(MarkNode * rap) ldNode *ip, *ip0; if (mp) print ( mp -> left); printf(" %6d: /t" ,mp -> mark); ip = mp -> head; while(ip) printf(" %6d" ,ip -> id); ip0 =ip; ip = ip -> next; free (ip0); printf(" /n" ); printf( mp -> right); free(mp);
问答题[说明]为了有效记录交通事故情况,欲设计一个交通事故记录系统。一辆汽车有一个唯一的“车牌号”,车主购买汽车时需要提供相关信息,包括身份证、姓名、年龄、性别、地址等。一个车主可以拥有多辆汽车,而一辆汽车只有一个车主。驾驶员不一定是车主,因此记录交通事故时要记录驾驶员身份证号,同时记录事故发生时刻。图2-1描绘了人、汽车、交通事故三个实体类型及实体间联系的一个E-R图。[图2-1]对应的关系模式为:·人(身份证号,姓名,性别,年龄,地址)·汽车(车牌号,型号)·事故(车牌号,身份证号,时刻,损失,描述)·拥有(身份证号,车牌号)
问答题【程序5说明】 设M叉树采用列表法表示,即每棵子树对应一个列表,列表的结构为:子树根结点的值部分(设为一个字符)和用“()”括起来的各子树的列表(如有子树的话),各子列表间用“,”分隔。例如下面的三叉树可用列表a(b(c,d),e,f(g,h,i))表示。 本程序输入列表,生成一棵M叉树,并由M叉树输出列表。假定输入无错误。 【程序5】 #include<Stdio.h> #include<Stdlib.h> #define M 3 typedef struct nodechar val; struct node,subTree[M]; NODE; char buf[255],*Str=buf; NODE * d=NULL NODE*makeTree()/*由列表生成M叉树*/ int k;NODE*s; s= (1) ; s->val= *Str++; for(k=0;k<M;k++)s->subTree[k]=NULL; if(* str='(') k=0; dostr++; s->sub Tree[k]= (2) ; if(*Str==')')Str++;break; k=k+1; while( (3) ); return s; void walkTree(NODE*t)/*由M又树输出列表*/ int i; if(t!=NULL) (4) if(t->subTree[0]==NULL)return; putchar('('); for(i=0;i<M;i++) (5) ; if(i!=M-1&&t->subTree[i+1]!=NULL) putchar(','); putchar(')'); void main() printf("Enter exp:"); scanf("%s",str); d=makeTree(); walkTree(d);putchar('/n");