问答题下列给定程序中,函数fun()的功能是:对N名学生的学习成绩,按从高到低的顺序找出前m(m≤10)名学生来,并将这些学生数据存放在一个动态分配的连续存储区中,此存储区的首地址作为函数值返回。注意:部分源程序给出如下。请勿改动主函数main和其他函数中的任何内容,仅在函数fun()的横线上填入所编写的若干表达式或语句。试题程序:#include<stdio.h>#include<malloc.h>#include<string.h>#include<conio.h>#defineN10typedefstructss{charnum[10];intorder;}STU;STU*fun(STUa[],intm){STUb[N],*tt;inti,j,k;{{U}}(1){{/U}};for(i=0;i<N;i++)b[i]=a[i];for(k=0;k<m;k++){for(i=j=0;i<N;i++)if({{U}}(2){{/U}})j=i;tt[k]=b[j];b[j].order=0;}return{{U}}(3){{/U}};}outresult(STUa[],FILE*pf){inti;for(i=0;i<N;i++)fprintf(pf,"No=%sMark=%d/n",a[i].num,a[i].order);fprintf(pf,"/n/n");}main(){STU[N]={{"A01",80},{"A02",79},{"A03",66},{"A04",82},{"A05",87},{"A06",93},{"A07",78},{"A08",60},{"A09",85},{"A10",73}};STU*p_order;inti,m;clrscr();printf("***TheOrigialdata***/n");outresult(a,stdout);printf("/nGivethenumeberofthestudentswhohavebetterscore:");scanf("%d",&m);while(m>10){printf("/nGivethenumberofthestudetswhohavebetterscore:");scanf("%d",&m);}p_order=fun(a,m);printf("***THERESULT***/n");printf("***Thetopstudents***/n");for(i=0;i<m;i++)printf("%s%d/n",p_order[i].num,p_order[i].order);free(p_order);}
问答题阅读下列说明、流程图和算法,将应填入{{U}}(n){{/U}}处的字句写在答题纸的对应栏内。【说明】下面的流程图1—5用N-S盒图形式描述了数组A中的元素被划分的过程。其划分方法是:以数组中的第一个元素作为基准数,将小于基准数的元素向低下标端移动,而大于基准数的元素向高下标端移动。当划分结束时,基准数定位于A[i],并且数组中下标小于i的元素的值均小于基准数,下标大于i的元素的值均大于基准数。设数组A的下界为low,上界为high,数组中的元素互不相同。例如,对数组(4,2,8,3,6),以4为基准数的划分过程如下:【流程图】【算法说明】将上述划分的思想进一步用于被划分出的数组的两部分,就可以对整个数组实现递增排序。设函数血p(intA[],intlow,inthigh)实现了上述流程图的划分过程并返回基准数在数组A中的下标。递归函数voidsort(intA[],ihtL;intH)的功能是实现数组A中元素的递增排序。【算法】voidsort(intA[],int1,intH){if(L<H){k=p(A,L,R)://p()返回基准数在数组A中的下标sort({{U}}(4){{/U}});//小于基准数的元素排序sort({{U}}(5){{/U}});//大于基准数的元素排序}}
问答题【说明】构造最优二叉查找树。 具有n个结点的有序序列a1, a2, …, an存在于数组元素a[1]、a[2], …, a[n]之中, a[0]未被使用。结点a1, a2, …, an-1, an的查找成功的概率p1, p2, …, pn-1, pn存在于数组元素 p[1]、p[2], …, p[n—1]、p[n]之中, p[0]未用。另外, 查找失败的概率q0, q1, …, qn-1, qn存在于数组元素q[0]、p[1], …, q[n-1]、q[n]之中。算法计算的序列ai+1, ai+2,…, aj-1, aj的最优二叉查找树Tij的代价Cij存在于数组元素c[i][j]之中, Tij的根结点的序号rij存在于r[i][j]之中, 它的权值存在于w[i][j]之中。为了便于内存的动态分配, 统统使用一维数组取代二维数组。 const float MAXNUM=99999. 0; //尽可能大的浮点数 template<{{U}} (1) {{/U}}> void OPtimal_Binary_Search_Tree(float p[], float q[], Type a[], int n) { float *C, *W; c={{U}} (2) {{/U}}; w={{U}} (3) {{/U}}; int *r; r=new int[(n+1)*(n+1)]; for(i=0; i<=n; i++) { c[i*(n+1)+i]=0. 0; // 即:c[i][i]=0.0, 用一维数组表示 w[i*(n+1)+i]=q[i]; // 即:w[i][i]=q[i], 用一维数组表示 } int i, j, k, m, length; // m表示根结点的下标或序号, 范围为0~n float minimum; for(length=1; length<=n; length++) //处理的序列长度由1到n for(i=0; i<=n-length; i++){ //i为二叉查找树Tij的起始序号 j=i + length; //j为二叉查找树Tij的终止序号。如:处理序列a1a2a3时, //相应的二叉查找树为T03, i=0, 而j=3 w[i*(n+1)+j]={{U}} (4) {{/U}}; minimum =MAXMUM; for(k=i+1; k<=j; k++) //考察以ai+1、ai+2, …, ai为根的情况 if({{U}} (5) {{/U}}<minimum) { minimum=c[i*(n+1)+k-1]+c[k*(n+1)+j];m=k; } c[i*(n+1)+j]=w[i*(n+1)+j]+c[i*(n+1)+m-1]+c[m*(n+1)+j]; r[i*(n+1)+j]=m; // r[i][j]=m } } //构造好的最优二叉查找树的根结点的序号在r[0][n]中
问答题试题六(15分)阅读以下说明和Java代码,将应填入(n)处的字句写在答题纸的对应栏内。[说明]某绘图系统存在Point、Line、Square三种图元,它们具有Shape接口,图元的类图关系如图6-1所示。现要将Circle图元加入此绘图系统以实现功能扩充。已知某第三方库已经提供了XCircle类,且完全满足系统新增的Circle图元所需的功能,但XCircle不是由Shape派生而来,它提供的接口不能被系统直接使用。代码6-1既使用了XCircle又遵循了Shape规定的接口,既避免了从头开发一个新的Circle类,又可以不修改绘图系统中已经定义的接口。代码6-2根据用户指定的参数生成特定的图元实例,并对之进行显示操作。绘图系统定义的接口与XCircle提供的显示接口及其功能如下表所示:[图6-1]
问答题【说明】下面是某租车信息管理系统的介绍:该车库中备有若干车辆,每辆车有车号、车牌、车名、价格等属性。车库不定期地购买并注册新车供用户借用,也可将报废的旧车注销以停止租用。车库可为众多用户提供服务。每个用户在借车之前需注册姓名、地址等内容。每个用户最多可同时借3辆车。每辆车借期7天:若有一辆车超期,则不可再借其他车。一辆车超期一天罚款250元。若一辆车超期3周不归还,则发布通告。若用户借的车丢失,在罚款处理之前不能借车,每辆报失的车罚款该车目前市价(包括折旧)的1.2倍。注册新用户不受限制;而注销用户之前,该用户必须归还所有借的车,或者报失并接受罚款。【状态图1】【状态图2】1.【问题1】分析车辆的状态和事件,指出图2-1中的(1)、(2)、(3)、(4)分别是什么?
问答题一般的树结构常采用孩子-兄弟表示法表示,即用二叉链表作为树的存储结构,链表中结点的两个链域分别指向该结点的第一个孩子结点和下一个兄弟结点。例如,如图(a)所示的树的孩子一兄弟表示如图(b)所示。函数LevelTraVerse()的功能是对给定树进行层序遍历。例如,当对图(a)中的树进行层序遍历时,结点的访问次序为DBAEFPC。对树进行层序遍历时使用了队列结构,实现队列基本操作的函数原型如表所示。实现队列基本操作的函数原型表函数原型说明VoidInitQueue(Queue*Q)初始化队列BoolIsEmpty(QueueQ)判断队列是否为空,若是则返回TRUE,否则返回FALSEVoidEnQueue(Queue*Q,TreeNodep)元素入队列VoidDeQueue(Queue*Q,TreeNode*p)元素出队列Bool、Status类型定义如下:typedefenum{FALSE=0,TRUE=1}Bool;typedefenum{OVERFLOW=-2,UNDERFLOW=-1,ERROR=0,OK=1}Status;树的二叉链表结点定义如下:typedefstructNode{chardata;structNode*firstchiid,*nextbrother;}Node,*TreeNode;[函数代码]StatusLevelTraverse(TreeNoderoot){/*层序遍历树,树采用孩子-兄弟表示法,root是树根结点的指针*/QueuetemQ;TreeNodeptr,brotherptr;if(!root)returnERROR;InitQueue(&tempQ);{{U}}{{U}}{{/U}}{{/U}};brotherptr=root->nextbrother;while(brotherptr){EnQueue(&tempQ,brotherptr);{{U}}{{U}}{{/U}}{{/U}};}/*end-while*/while({{U}}{{U}}{{/U}}{{/U}}){{{U}}{{U}}{{/U}}{{/U}};printf(”%c/t”,ptr->data);if({{U}}{{U}}{{/U}}{{/U}})continue;{{U}}{{U}}{{/U}}{{/U}};brotherptr=ptr->firstchild->nextbrother;while(brotherptr){EnQueue(&tempQ,brotherptr);{{U}}{{U}}{{/U}}{{/U}};}/*end-while*/}/*end-while*/returnOK;}/*LevelTraverse*/
问答题【说明】
函数DeleteNode (Bitree *r, int e)的功能是:在树根结点指针为r的二叉查找(排序)树上删除键值为e的结点,若删除成功,则函数返回0,否则函数返回-1。二叉查找树结点的类型定义为:
typedef struct Tnode{
int data; /*结点的键值*/
struct Tnode *Lchild, *Rchild; /*指向左、右子树的指针*/
}*Bitree:
在二叉查找树上删除一个结点时,要考虑3种情况:
①若待删除的结点p是叶子结点,则直接删除该结点;
②若待删除的结点p只有一个子结点,则将这个子结点与待删除结点的父结点直接连接,然后删除结点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(e<p->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}}) {{/U}}c=p->Lchild;
else c=p->Rchild;
if(p==*r) *r=c;
else if {{U}}({{U}} (5) {{/U}}) {{/U}}pp->Lchild=c;
else pp->Rchild=c;
free (p);
return 0;
}
问答题【说明】
下面的程序先构造Point类,再顺序构造Ball类。由于在类Ball中不能直接存取类Point中的xCoordinate及yCoordinate属性值,Ball中的toString方法调用Point类中的toStrinS方法输出中心点的值。在MovingBsll类的toString方法中,super.toString调用父类Ball的toString方法输出类Ball中声明的属性值。
【Java代码】
//Point.java文件
public class Point{
private double xCoordinate;
private double yCoordinate;
public Point(){}
public Point(double x,double y){
xCoordinate=x;
yCoordinate=y;
}
public String toStrthg(){
return"("+Double.toString(xCoordinate)+","
+Double.toString(yCoordinate)+")";
}
//other methods
}
//Ball.java文件
public class Ball{
private{{U}} (1) {{/U}};//中心点
private double radius;//半径
private String color;//颜色
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个参数的构造方法
color=c;
}
public String toString(){
return "A ball with center"+center.toString()
+",radius "+Double.toString(radius)+",color"+color;
}
//other methods
}
class MovingBall{{U}} (4) {{/U}}{
private double speed;
public MovingBall(){}
public MoyingBall(double xValue, double yValue, double r, String c, double s){
{{U}} (5) {{/U}};//调用父类Ball中具有4个参数的构造方法
speed=s;
}
public String toString(){
return super.toString()+",speed"+Double.toString(speed);
}
//other methods
}
public class test{
public static void main(String args[]){
MovingBall mb=new MovingBall(10,20,40,"green",25);
System.out.println(mb);
}
}
问答题【说明】 以下C++程序的功能是计算三角形、矩形和正方形的面积并输出。程序由4个类组成:类 Triangle、Rectangle和Square分别表示三角形、矩形和正方形:抽象类Figure提供了一个纯虚函数getAxea(),作为计算上述3种图形面积的通用接口。 【C++代码】 #include<iostream> #include<cmath> using namespace std; class Figure public: virtual double getArea()=0;//纯虚函数 ; class Rectangle : (1) protected: double height; double width; public: Rectangle() Rectangle(double height, double width) this->height=height; this->width=width; double getArea() return (2) ; ;class Square: (3) public: Square(double width) (4) ; ; class Triangle: (5) private: double la,lb,lc;public: Triangle(double la,double lb,double lc) this->la=la;this->1b=1b;this->lc=lc; double getArea() double s=(la+lb+lc)/2.0; return sqrt(s*(s-la)*(s-lb)*(s-lc)); int main() Figure *figures[3]=new Triangle(2,3,3),new Rectangle(5,8), new Square(5); for(int i=0;i<3;i++) cout<<"figures["<<i<<"]area="<<(figures[i])->getArea()<<endl; return 0;
问答题 阅读以下说明和流程图,回答问题1和问题2。
【说明】
某供销系统接受顾客的订货单,当库存中某配件的数量小于订购量或库存量低于一定数量时,向供应商发出采购单;当某配件的库存量大于或等于定购粮食,或者收到供应商的送货单并更新了库存后,向顾客发出提货单。该系统还可随时向总经理提供销售和库存情况表。该供销系统的分层数据流图中部分数据流和文件的组成如下:
文件 配件库存=配件号+配件名+规格+数量+允许的最低库存量
数据流 订货单=配件号+配件名+规格+数量+顾客名+地址
提货单=订货单+金额 采购单=配件号+配件名+规格+数量+供应商名+地址
送货单=配件号+配件名+规格+数量+金额
假定顶层图(如图6所示)是正确的,“供应商”文件已由其他系统生成。
问答题[说明]一般的树结构常采用孩子—兄弟表示法表示,即用二叉链表做树的存储结构,链表中节点的两个链域分别指向该节点的第一个孩子节点和下一个兄弟节点。例如,如图1-15(a)所示树的孩子—兄弟表示如图1-15(b)所示。函数LevelTraverse()的功能是对给定树进行层序遍历。例如,对如图1-15所示的树进行层序遍历时,节点的访问次序为DBAEFPC。对树进行层序遍历时使用了队列结构,实现队列基本操作的函数原型如表1-11所示。Bool、Status类型定义如下:树的二叉链表节点定义如下:{{B}}表1-11实现队列基本操作的函数原型表{{/B}}{{B}}函数原型{{/B}}{{B}}说明{{/B}}voidInitQueue(Queue*Q)初始化队列BoolIsEmpty(QueueQ)判断队列是否为空,若是则返回true,否则返回falsevoidEnQueue(Queue*Q,TreeNodep)元素入队列voidDeQueue(Queue*Q,TreeNode*p)元素出队列[C函数程序]
问答题某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图1所示。图1纸巾售卖机状态图采用状态(State)模式来实现该纸巾售卖机,得到如图2所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldState、SoldOutState、NoQuarterState和HasQuarterState分别对应图1中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有2元钱。图2用类图[C++代码]#include<iostream>usingnamespacestd;//以下为类的定义部分classTissueMachine;//类的提前引用classSrate{public:virtualvoidinsertQuarter()=0;//投币virtualvoidejectQuarter()=0;//退币virtualvoidturnCrank()=0;//按“出纸巾”按钮virtualvoiddispense()=0;//出纸巾};/*类SoldOutState、NoQuarterState、HasQuarterState、SoldState的定义省略,每个类中均定义了私有数据成员TissueMachine*tissueMachine;*/ClassTissueMachine{private:{{U}}{{U}}{{/U}}{{/U}}*soldOutState,*noQuarterState,*hasQuarterState,*soldState,*State;intcount;//纸巾数public:TissueMachine(intnumbers);voidSetState(State*state);State*getHasQuarterState();State*getNoQuarterState();State*getSoldState();State*getSoldoutState();intgetCount();//其余代码省略};//以下为类的实现部分voidNoQuarterState::insertQuarter(){tissueMachine->setState({{U}}{{U}}{{/U}}{{/U}});}voidHasQuarterstate::ejectQuarter(){tissueMachine->setState({{U}}{{U}}{{/U}}{{/U}});}voidSoldState::dispense(){if(tissueMachine->getCount()>0){tissueMachine->setState({{U}}{{U}}{{/U}}{{/U}});}else{tissueMachine->setState({{U}}{{U}}{{/U}}{{/U}});}}//其余代码省略
问答题[说明]对多个元素的聚合进行遍历访问时,需要依次推移元素,例如对数组通过递增下标的方式,数组下标功能抽象化、一般化的结果就称为迭代器(Iterator)。模式以下程序模拟将书籍(Book)放到书架(BookShelf)上并依次输出书名。这样就要涉及到遍历整个书架的过程。使用迭代器Iterator实现。图5-1显示了各个类间的关系。以下是C++语言实现,能够正确编译通过。[图5-1][C++代码]template(1)>classIteratorpublic:virtualboolhasNext()=0;(2)Object*next()=0;;classBook//省略具体方法和属性;classBookShelfprivate:vectorbooks;public:BookShelf()Book*getBookAt(intindex)returnintgetLength()returnbooks.size();;templateclassBookshelfIterator:public(3)private:BookShelf*bookShelf;intindex;public:BookshelfIterator(BookShelf*bookShelf)this->bookShelf=bookShelf;index=0;boolhasNext()//判断是否还有下一个元素if(indexgetLength())returntrue;elsereturnfalse;Objeot*next()//取得下一个元素returnbookShelf->getBookAt(index++);;intmain()BookShelfbookShelf;//将书籍上架,省略代码Book*book;Iterator*it=newBookShelfIterator((4));while((5))//遍历书架,输出书名book=(Book*)it->next();/*访问元素*/return0;
问答题[问题1]
如果将数据库服务器(记为DB)作为一个外部实体,那么在绘制该系统的数据流图时,还应有哪些外部实体和数据存储?
问答题[说明] 以下C程序实现了将字符串转化为浮点数的功能。例如字符串“1234567”转化为浮点数1234567;字符串“100.02035”转化为浮点数100.02035;字符串“-100.02035”转化为浮点数-100.02035。程序中的部分变量的含义如表9-5。 表9-5 变量名 含 义 intpart 字符串转化为浮点数后的整数部分 doublepart 字符串转化为浮点数后的小数部分 kdouble 记录小数部分的阶次 resoult 字符串转化为浮点数后的结果 psign 字符串转化为浮点数后的符号标识 [C程序] double StrToDouble(char*s) char hexch[]="0123456789"; int i,j,psign=1; DWORD n,k,intpart=0; double doublepart=0,kdouble,resoult; char ch; if (*s=='.' (1) ; (2) ; char*s1=s,*temp=NULL; temp=strrchr ( s1,'.' ); if (!temp) k=1; intpart=0; for (i=strlen (s); i>0;i--) ch=s[i-1]; if (ch>0x3f) ch n=0; for (j=0; j<10; j++) if ( ch==hexch[j]) n=j; intpart+= (n*k); k*=10; else s1=temp+1; kdouble=0.1; doublepart=0; for ((3) ) ch=s1[i-1]; if (ch>0x3f) ch n=0; for (j=0; j<10; j++ ) if (ch==hexch[j]) n=j; doublepart+= (n*kdouble); (4) ; *temp=NULL; k=1; intpart=0; for ((5) ;) ch=s[i-1]; if (ch>0x3f) ch n=0; for (j=0; j<10; j++) if (ch==hexch[j]) n=j; intpart+= (n*k); k*=10; //end else (6) ; return resoult;
问答题【说明】 下面是某医院信息管理系统中需要的信息。 科室:科名、科地址、科电话、医生姓名。 病房:病房号、床位号、所属科室名。 医生:姓名、职称、所属科室名、年龄、工作证号。 病人:病历号、姓名、性别、诊断、主管医生、病房。 其中,一个科室有多个病房,多个医生,一个病房只能属于一个科室,一个医生只属于一个科室,但可以负责多个病人的诊治,一个病人的主管医生只有一个。
问答题阅读下列说明和C代码,回答问题。 [说明]
设有n个货物要装入若干个容量为C的集装箱以便运输,这n个货物的体积分别为{S1,S2,…,Sn},且有si≤C(1≤i≤n)。为节省运输成本,用尽可能少的集装箱来装运这n个货物。
下面分别采用最先适宜策略和最优适宜策略来求解该问题。
最先适宜策略(Firstfit)首先将所有的集装箱初始化为空,对于所有货物,按照所给的次序,每次将一个货物装入第一个能容纳它的集装箱中。
最优适宜策略(Bestfit)与最先适宜策略类似,不同的是,总是把货物装到能容纳它且目前剩余容量最小的集装箱,使得该箱子装入货物后闲置空间最小。
[C代码] 下面是这两个算法的C语言核心代码。 {{U}}
1 {{/U}}变量说明。 n:货物数。 C:集装箱容量。
s:数组,长度为n,其中每个元素表示货物的体积,下标从0开始。
b:数组,长度为n,b[i]表示第i+1个集装箱当前已经装入货物的体积,下标从0。 i,j:循环变量。
k:所需的集装箱数。 min:当前所用的各集装箱装入了第i个货物后的最小剩余容量。
m:当前所需要的集装箱数。 temp:临时变量。 {{U}}
2 {{/U}}函数firstfit。 int firstfit(){
inti,j; k=0; for(i=0;i<n;i++){
b[i]=0; } for(i=0;i<n;i++){
{{U}} {{U}} 1 {{/U}} {{/U}};
while(C-b[j]<s[i]){ j++; }
{{U}} {{U}} 2 {{/U}} {{/U}};
k=k>(j+1)?k:(j+1); } returnk
} {{U}} 3 {{/U}}函数bestfit。 int
bestfit(){ int i,j,min,m,temp; k=0;
for(i=0;i<n;i++){ b[i]=0; }
for(i=0;i<n;i++){ min=C;
m=k+1; for(j=0;j<k+1;j++){
temp=C-b[j]-s[i]; if(temp>0&&temp<min){
{{U}} {{U}} 3 {{/U}} {{/U}}; m=j;
} } {{U}} {{U}} 4
{{/U}} {{/U}}; k=k>(m+1)?k:(m+1);
} return k; }
问答题【说明】C市刚开通了地铁线,为方便乘客,计划开发自动售票系统。该公司在每一个地铁站放置了多台自动售票机,每一台售票机有一唯一编号,售票记录统一汇总主机。自动售票机只发售从该站起始的各种地铁票,因此乘客只需输入目的站,起始站默认为该站,售票机给出从该站到达目的站的单程票。打印地铁票时为其编一个唯一的流水号,并同时打印自动售票机的编号及票价。售票机的状态变化如下:“空闲”时,显示地铁线路图,等待乘客输入目的站;当乘客输入目的站后,转入“目的站确认/票数输入”状态,同时给出票价,此时若目的站有误,可返回到空闲状态重新输入,否则,输入票数;乘客输入票数后,转入“票数确认/付款”状态,同样此时若票数有误,可返回到上一状态重新输入,否则,投入钱币付款;当付款金额足够时,“出票/找零”(有必要时进行找零);然后转入“空闲”等待输入目的站状态。该系统采用面向对象方法开发,系统中的类及类之间的关系用UML类图表示,如图9-18所示是该系统类图的一部分,图9-19描述了自动售票机的状态转换图。
问答题[说明]已知某企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批。主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开会讨论决定。采用责任链设计模式(ChainofResponsibility)对上述过程进行设计后得到的类图如图3-27所示。[C++代码]
问答题[说明]公司IT部门决定开发一个计算机管理系统以记录期刊的传阅情况。期刊在公司内部传阅,员工可以要求加入传阅队列。图书室登记公司收到的期刊,交给名单中的第一名员工。员工应在三个工作日内完成阅读,员工阅读完毕后通知系统,系统提醒下一位阅读者取书,下一个员工必须确认已收到期刊。当传阅名单中“下一位”员工出差在外时将无法进行传阅,此时将期刊传给再下一位,而将该员工作标记,再次传递此书时优先考虑该员工。最后一位员工阅读完毕后,将期刊交还图书室以便共用。系统能在员工忘记传递期刊时发出提醒信息。系统详细记录期刊传阅情况,当员工阅读完后通知系统,系统记录该员工员工号及日期,并在备注栏注明是传出;同样,当员工收到期刊后给系统确认,系统记录该员工员工号及日期,并在备注栏注明是收到。公司的员工都有一个唯一的员工号。公司订阅了多种期刊,为每一本期刊(有唯一期刊流水号)产生一份传阅名单,并详细记录传阅情况。员工的出差情况存储在系统主机中。该系统采用面向对象方法开发,系统中的类以及类之间的关系用UML类图表示,图1-1是该系统的类图的一部分,图1-2描述了成功传递期刊的序列图。[图1-1][图1-2]1.根据题意,给出类“传阅记录”的主要属性。
