一九九八年度高级程序员级 下午试卷

发表于:2007-05-26来源:作者:点击数: 标签:
试题一 阅读以下说明和流程图,回答问题 1至问题3,将解答写在答卷的对应栏 [ 说明 ] 本流程图描述某超市销售数据的部分处理流程。超市中有若干台收款机和若干名收款员。这 里,我们把一个收款员开始使用一台收款机到离开这台收款机称为该收款员的一次作业。

试题一

  阅读以下说明和流程图,回答问题 1至问题3,将解答写在答卷的对应栏

[说明]

  本流程图描述某超市销售数据的部分处理流程。超市中有若干台收款机和若干名收款员。这

里,我们把一个收款员开始使用一台收款机到离开这台收款机称为该收款员的一次作业。作业开始时,收款员先在收款机上输入收款员号和作业前金额。作业前金额是为了销售时的找零而在作业前预先放入钱箱的金额数。作业结束时,收款员要找开钱柜,取走全部现金,并把这些现金的金额数(称为作业后金额)输入收款机。当

    作业前金额+本次作业售货总金额-本次作业退货总金额≠作业后金额

时,表示这次作业存在金额差错。

  本流程图已作简化,并作以下假定;该超市只有现金交易(不用信用卡和礼券);一个收款员因某种原因(如吃饭)在一天中可以有多个作业;销售方式只有售货和退货两种。

  整个超市分成若干部门(如食品部、服装部),系统按部门统计一个月中各类货物的销售数量和金额,最后根据月销售计划文件分析各部门完成销售计划的情况。系统还统计每个收款员的差错情况和退货情况。

  图中处理4和处理8每月的最后一天执行一次(营业结束后),其它处理每天执行一次。

  图中部分数据、文件的记录格式如下:

  日销售数据:收款机号十收款员号十作业前金额十

        {(售货标记|退货标记)十货号十数量十单价十金额}+作业后金额

  日销售文件记录:(作业开始标记十收款机号十收款员号十作业前金额 )

          |(售货标记|退货标记)十货号十数量十金额) )

          |(作业结束标记十收款机号十收款员号十作业后金额

  部门日销售文件记录:部门号十(售货标记|退货标记)十货号十数量+金额

  部门月销售计划文件记录;部门号十月计划金额

  收款员差错月报:月份十收款员号十差错作业数十差错总金额

  收款员退货月报..月份十收款员号十退货次数十退货总金额

  其中 {w}表示 w重复出现多次; a|b 表示 a或b; a+b表示 a与b。

[问题1]

  分别写出收款员日销售文件、商品文件、部门日销售汇总文件至少应包含哪些数据项。

[问题2]

  处理1能检查出日销售数据中的哪些错误。

[问题3]

  处理4对收款员月销售文件作何种操作。

试题二

  阅读以下说明和流程图,回答问题,将解答写在答卷的对应栏内。

[说明

  本流程图描述了某子程序的处理流程,现要求用白盒测试法为该子程序设计测度数据

[问题]

  根据判定覆盖、条件覆盖、判定一条件覆盖、条件组合覆盖(即多重条件覆盖)、路径覆盖等五种覆盖标准,从供选择的答案中分别找出满足相应覆盖标准的最小测试数据组(用①~12回答)。 供选择的答案

      ①x=90,y=90  ②x=90,y=70  ③x=90,y=90  ④x=90,y=75

       x=70,y=70   x=70,y=90   x=90,y=75   x=75,y=90

                        x=75,v=90   x=70,y=70

      ⑤x=90,y=90  ⑥x=80,y=80  ⑦x=80,y=80  ⑧x=80,y=80

       x=90,y=75   x=90,y=70   x=90,y=75   x=90,y=70

       x=75,y=90   x=70,y=90   x=90,y=90   x=70,y=90

       x=70,y=70   x=70,y=70   x=75,y=90   x=70,y=70

                        x=70,y=70   x=70,y=75

      ⑨x=80,y=80  ⑩x=90,y=90  11. x=80,y=80 12. x=80,y=80

       x=90,y=75   x=90,y=75   x=90,y=75   x=80,y=70

       x=90,y=70   x=90,y=70   x=90,y=70   x=70,y=80

       x=70,y=80   x=75,y=90   x=70,y=80   x=70,y=70

       x=70,y=75   x=70,y=70   x=70,y=75   x=90,y=75

       x=70,y=70   x=70,y=90   x=70,y=70   x=90,y=70

                        x=70,y=90   x=70,y=75

                                 x=75,y=90

                                 x=75,y=80

                                 x=70,y=90

试题三

  阅读以下说明和流程图,回答问题1至问题2,将解答写在答卷的对应栏内。

[说明]

  本流程图描述了某种字符序列的变换过程。变换前的字符序列以字符“#”结尾,它存放在数组old中,变换后的字符序列存放在数组new中,它不包含结束标志“#”。流程图按下列规则进行变换:

 1.删除字符序列中的注解。注解用一对“!”字符分隔,注解中可出现除“#”外的任何字符。

 2.字符常数完整地保留。字符常数用一对“&”字符分隔,字符常数中可出现、外的任何字符。

  值得注意的是:当字符“&”需要出现在字符常数中时,通常用二个连续的“&”表示,在

  保留字符常数时,这二个连续的“&”都被保留。此外,作为字符常数分隔符的一对“&”

  也被保留。

 3.除字符常数和注解外,出现在其它地方的连续多个空格压缩成一个空格,但字符序列中先导

  的空格则全部删除。

 4.注解和字符常数之外的非空格字符均保持不变。

  本流程图对原字符序列从左到右扫描,根据遇到的当前字符来搜索连续空格、注解或字符常

  数,然后按上述变换规则变换。若遇到的当前字符是“!”,则寻找下一个“!”字符(若

  找不到则作出错处理),这二个“!”间的字符全部看作为注解。若当前字符是“&”字符

  则寻找与之配对的下一个“&”字符(若找不到则作出错处理),其间的字符全部看作为字

  符常数。

  例如:

  原字符序列:

  └┘└┘a└┘└┘└┘b&cd&&└┘└┘!e&f└┘└┘ g!h& └┘└┘!└┘└┘j#

  变换后的字符序列:a└┘bdcd&&└┘└┘!e&f└┘g└┘j

  本流程图假定在数组old中一定存在“#”字符。

[问题1]

  填充流程图中的①~⑤,把解答写在答卷的相应位置上。

[问题2]

  当原字符序列中汪解的前后均是连续空格时,本流程图将注解前后的连续空格分别压缩成一个空格,删除注解后,将导致变换后的新字符序列出现二个连续的空格。如;

           g└┘└┘!h&└┘└┘i!└┘└┘j

本流程图将变换成g└┘└┘j。

  为使变换后的新序列中除字符常数外没有连续的空格,图中的虚线框需作何改动(只需画出修改后的流程图)

试题四

  在COMET型计算机上可以使用试卷上所附的CASL汇编语言。阅读以下程序说明和CASL程序,将应填入_(n)_处的字句,写在答卷的对应栏内。

[程序说明]

  本程序是统计字符串中数字字符“0”至“9”的出现次数。

  字符串中的每个字符是用ASCII码存贮。一个存贮单元存放两个字符,每个字符占8位二进位。

  程序中,被统计的字符串从左至右存放在STR开始的连续单元中,并假定其长度不超过200,字符串以‘·’符作为结束。NCH开始的10个单元存放统计结果。

   START MIN

MIN  LEA GR2,9

   LEA GR0,0

L1  _(1)_

   LEA GR2,-1,GR2

   LEA GR4,0

   LEA GR1,0

L2  LD GR2,STR,GR1

   EOR GR4,C1

   JNZ RL

   _(2)_

RL  SRL GR2,8

   LEA GR3,0,GR2

   SUB BR3,C9

   JNZ L4

L3  LEA GR3,0,GR2

   SUB GR3,CO

   JM1 L5

   LEA GR2,1

   _(3)_

   _(4)_

L4  GR4 0,GR4

   JNZ L2

   _(5)_

   JMP L2

L5  SUB GR2,C

   JNZ L4

   EXIT

C1  DC 1

C   DC '·'

C0  DC '0'

C9  DC 9

STR  DS 200

NCH  DS 10

   END

试题五

  阅读以下程序说明和C程序,将应填入_(n)_处的字句,写在答卷的对应栏内。

[程序说明]

  这里给出的程序逐一从指走课程成绩文件中读入学生的学号和成绩,对同一学生汇总他的总成绩,并按以下格式输出名次(按总成绩由高到低的顺序)、总成绩、同一名次的学生人数、同一名次学生的学号(按学号由小到大的顺序)。

  程序约定学生学习课程不超过30种,课程成绩文件的第一个数字就是课程号,统计过程中,同一课程号的成绩文件不能重复输入。

  程序采用链表结构存储学生有关信息,链表中的每个表元对应一位学生。程序在数据输入过程中,形成一个按学生学号从小到大顺序链接的有序链表。当数据输入结束后,程序按总成绩从高到低,学号从小到大的顺序对链表排序。程序最后按指定格式输出链表中的信息。程序的输出格式如下例所示:

名 次 总成绩 人 数 学 号    
1 470 2 12 25  
3 450 3 15 24 50
6 430 1 14    
7 401 3 13 18 45
         

[程序]

#include 〈stdio.h〉

#define M 30

#define NLEN 10

typedef struct node {int cur_s/*最近输入成绩的科目 */

          char no[NLEN];int score;

          stuction node *next;

           }NODE;

N0DE*bubblesort(N0DE*head)

{NODE *q,*tail,*p=(MODE*)malloc(sizeof(NODE);

 p→next=head;head=p;tail=NULL;

 while (tail!=___(1)___)

 {p=head;q=p→next;

  while (q→enxt!=tail)

  {if (p→next→score→〈q→next→score||

     p→next→scor==q→next→score&&

     strcmp(p→next→no,q→next→no)〉0)

   {p→next=_(2)_,/*两相邻表元链接关系前后颠倒*/

    _(3)_=q→next→next;p→next→next=q;

   }

   p=p→next;/*调整p和q*/ q=_(4)_;

  }

  tail=q;

 }

 p=head→next;free(head);return p;

}

int s[M],sp;

main()

{FILE*fp;

 NODE*h,*u,*v*p;

 int ss,,mark,order,c;

 char fname[80],no[NLEN],ans;

 for(h=NULL,sp=0;;)

 {print(''输入科目成绩文件名(输入aaaa表示强行结束)。\n");

  while (1)

  {scanf("%s",fname);

   if(strcmp(fname,"aaaa")==0)break;

   if((fp=fopen(fname,"r"))==NULL)

    printf("不能打开文件%s,请重新输入科目文件名。\n,fname);

   else break;

  }

  if(strcmp(fname,"aaaa")==0)break;

  fscanf(fp,"%d",&ss);/·输入科目号·/s[sp]=ss;

  for(i=0;s[i]!=ss;i++);

  if(i<sp)

  {printf("该科目的成绩已输入,请输入别的科目成绩文件。\n");

   continue;

  }

  sp++;

  while(fscanf(fp,"%s%d",no,&mark)==2)

  {/*在链表中寻找最近输入的学号*/

   for(v=h;v!=NULL,&& strcmp(v→no,no)<0;u=v,v=v→next);

   if(v!=NULL && strcmp(v→no,no)==0)

   {if (v→cur_s!==ss)

    {v→score+=mark;v→cur_s=ss;

    }/*同一科目成绩的重复输入,后输入成绩被忽略*/

   }else {p=(NODE*)malloc(sizeof(node);/*一位新的学生*/

       strcpy(p→no,no);p→score=mark;p→cur_s=ss;

       p→next=v;

       if(v==h) h=p;else u→next=p;

      }

  } fclose(fp);

  printf("还有科目成绩文件要输入吗?(Y/N)");scanf("%c",&ans);

  if(anns=='N'||ans=='n')break;

 }

 h=bubblesort(h);

 printf("名次 总成绩 人数 学号\n");/*以下按格式要求输出*/

 v=h;order=1;

 while(v!=NULL)

 {for (c=1,u=v→next;u!NULL &&u→score==v→score;c++,u=u→next);

  printf("%4d%7d%8d ",order,v→score,c);

  for(order+=c,i=1;_(5)_;v=v→next,i++)

  {if (i>1 && i%5==1) printf("\n%23c",'');

   printf("%s",v→no);

  }printf("\n");

 }

}

试题六

  阅读以下程序说明和FORTRAN程序,将应填入_(n)_处的字句,写在答卷的对应栏内。

[程序说明]

  本程序用以将m+n个元素的数组A中的前m个元素(A(1)-A(m))与后n个元素(A(m+l)-A(m+n))互换位置,并保持其各自原有的内部顺序。

  程序中把数组的各元素看成首尾相连的序列,并将数组元素分成G组(G为m和n的最大公因子),每组中的元素序列是从数组某元素起由间隔为m的元素组成,再将每组元素依次循环向左传送,即得所需结果。

  例如原数组A为:

             

  由m=4,n=2,求得 G=2,将A中的元数分成两组。按上述说明,第一组元素序列依次为A(1)、A(5)、A(3),将它们循环向左传送后的结果为

8 9 7 2 6 4

  第二组元素序列依次为以A(2)、A(6)、A(4),将它们循环向左传送后的结果为

8 4 7 9 6 2

即得所需结果。

   INTEGET A(1000), G,H

   READ(*,*)M,N

   READ(*,*)(A(1),1=1,M+N)

   G=M

   H=N

20  IF (G,NE,H)THEN

    IF(G,GT,T)THEN

     G=G-H

    ELSE

     H=H-G

    ENDIF

    GOTO 20

   ENDIF

   DO 100 I=_(1)_

    TEMP=A(1)

    K=1

30   J=_(2)_

    IF(J,NE,1)THEN

     A(K)=_(3)_

     K=J

     _(4)_

    ELSE

     A=K=_(5)_

    ENDIF

100  CONTINUE

   WRITE(*,200)(A(I),I=1,M+N)

200  FORMANT(1016)

   END

试题七

  阅读以下程序说明和C程序,将应填入_(n)_处的字句,写在答卷的对应栏内。

[程序说明]

  本程序的函数

     sum(int,i int total,int sigma,int rear,int d[],int n)

用来从已知数组d的前n个元素中找出所有部分元素序列之和等于total的元素序列,约定数组d的元素都是正整数,且都小于等于total。

  函数sum使用递归方法找出全部解答。参数i表示递归函数当前考虑元素d[i],参数sigma是调用前已选取的部分序列的元素和,参数rear是后面还未考虑的那部分元素的元素和。

  函数对元素d[i]有两种可能的选择方案:

  1.考虑元素d[i]被包含在新的部分元素序列中的可能性。如果在当前部分元素序列之后接上d[i],新序列的元素和不超过total,则函数将d[i]包含在当前部分元素序列中。如果新的部分元素序列的元素和等于total时,新的部分元素序列就是一个解答,函数将其输出;否则,若继续考虑后面的元素还有可能找到解答时,函数就递归去考虑后面的元素,寻找解答。最后,函烽就恢复原来部分元素序列中不包含d[i]的状态。

  2.考虑元素d[i]不被包含在新的部分元素序列中的可能性。如果继续向d[i]之后考虑还是有希望能得到和为total的部分元素序列时,函数将新序列不包含d[i]也作为一种可能的选择,并递归去考虑后面的元素,寻找解答。

#include 〈stdio.h〉

#define N 100

int a[N];

int flg[N];

sum (int i,int total,int sigma,int rear,int d[],int t)

{int j;

 /*考虑元素d[i]被包含在新的部分元素序列中的可能性 */

 if(sigma+d[i] total/*如果d[i]与当前序列的和不超过total*/

 {flg[i]=1;/*d[i]被考虑在被部分元素序列中 */

  if(_(1)_==total)

  {/*输出解*/

   for (j=0;flg[j]==0;j++);

   printf("%4d=%d",total,d[j]);

   for(j++;<=i;j++)

     if (flg[j])

       printf("+%d",d[j]);

   printf("\");

  }

  else /*并且继续考虑后面的元素有可能找到解答时 */

  if(i<n-1 &&rear-d[i]+sigma>=total)

    sum(i+1,total,_(2)_,rear-d[i],d,n);

  _(3)_;

 /*考虑元素d[i]不被包含在新的部分元素序列中的可能性。*/

 if (i<n-1&&rear-d[i]+tigma>=total)

     sum(i+1,total,_(4),rear-d[i],d,n);

}

main()

{int i,j,n,total,s,d;

 printf("输入total!/n");scanf("%d",&total);

 printf("输入n!/n"); scanf("%d",&n);

 for (s=i=0;i<n;)

 {printf ("输入第%d个元素>0且<=%d)\n",i+1,total);

  scanf ("%d",&d);

  if( d<1||d>total)

   {printf("出错,请重新输入!\n");

     contnue;

   }

   s+=a[i++]=d;

 }

 sum(0,total,0,_(5)_,a,n);

 printf ("\n\n");

}

试题八

  阅读以下程序说明和FORTRAN程序,将应填入_(n)_处的字句,写在答卷的对应栏内。

[程序说明]

  本程序用以查找给定数组A的第K小元素。程序执行后,第K小元素存放在数组元素A(K)中。

  设给定的数组中各元素A(i)=(i=1,2…N)互为不相等。它的第K(1≤k≤N)小元素是指这样的元素;它大于N个元素中的K-1个元素,而小于其余的N-K个元素。假如,假设N=8,数组A为:

44 94 12 50 55 6 18 67

它的第5小元素(即K=5)是50。

  本程序的处理过程如下:

  将A(K)的值(此例为A(5),此时值为55)存入X,从左向右扫描,直至遇以第一个不小于X的元素(此时为94),再从右向左扫描,直到遇见第一个不大于X的元素(此时为18),然后交换这两个元素,数且A成为:

44 18 12 50 55 6 94 67

继续这一“扫描与交换”的过程,直到两个方向的扫描在数组中间的某处汇合。此时数组被分成两段,汇合点左边的元素均小于汇合点右边的元素。然后选取存在第K小元素的一段,重复上述扫描、交换和调整扫描范围的处理过程。程序中采用L、R来表示扫描的范围的左右边界。开始时L为1,R为N,以后逐次调整。当变成为L值不小于R值时,A[K]即是第K小元素。

   SUBROUTINT FIND(A,N,K)

   INTEGET A(N),R,X,W

   L=1

   R=N

20  IF (L,LT,R)THEN

    X=A(K)

    I=L

    J=R

30   IF(A(1),LT,X)THEN

     I=I+1

     GOTO 30

    ENDIF

40   IF(___(1)___)THEN

     ___(2)___

     GOTO 40

    ENDIF

    IF(I,LE,J)THEN

     W=A(I)

     ___(3)___

     I=I+1

     ___(4)___

    IF(I,LE,J)___(5)___

    ENDIF

    IF(J,LT,K)L=I

    IF(___(6)___) R=___(7)___

    GOTO 20

   ENDIF

   RETURN

   END

原文转自:http://www.ltesting.net