201311程序员下午真题

第 1 题

阅读以下说明和流程图,填补流程空中的空缺(1)~(5)将解答填入答题纸的对应栏内。
【说明】
两个包含有限个元素的非空集合 A、B  的相似度定义为 |A∩B|/|A∪B|,即它们的交集大小(元素个数)与并集大小之比。
以下的流程图计算两个非空整数集合(以数组表示)的交集和井集,并计算其相似度。己知整数组 A[1:m]和 B[1:n]分别存储了集合 A 和 B 的元素(每个集合中包含的元素各不相同),其交集存放于数组C[1:s],并集存放于数组D[1:t] ,集合A 和 B 的相似度存放于 SIM。
例如,假设 A={ 1, 2 ,3,4} ,B={ 1, 4 ,5,6},则C={1, 4} ,D={1, 2 ,3 ,4 ,5, 6},A 与 B 的相似度 SIM=1/3。

【流程图】


答案与解析

  • 试题难度:较难
  • 知识点:流程图>流程图
  • 试题答案:(1)s             (2)t      (3)c[s]           (4)D[t] (5)s/t
  • 试题解析:本题考查程序处理流程图的设计能力。
    首先我们来理解两个有限集合的相似度自含义。两个包含有限个元素的非空集合 A、B 的相似度定义为它们的交集大小(元素个数)与并集大小之比。如果两集合完全相等,则相似度必然为 1 (100%); 如果两集合完全X同(没有公共元素),则相似度必然为0; 如果集合A 中有一半元素就是集合B 的全部元素,而另一半元素不属于集合 B,则这两 个集合的相似度为 0.5(50%)。因此,这个定义符合人们的常理性认识。
    在大数据应用中,经常要将很多有限集边行分类。例如,每天都有大量的新闻稿。
    为了方便用户检索,需要将新闻稿分类。用付么标准来分类呢?每一篇新闻稿可以用其 中所有的关键词来表征。这些关键词的集合勒为这篇新闻稿的特征向量。两篇新闻稿是 否属于同一类,依赖于它们的关键词集合是否具有较高的相似度(公共关键词个数除以 总关键词个数)。搜索引擎可以将相似度超过一定水平的新闻稿作为同一类。从而,可以 将每天的新闻稿进行分类,就可以按用户的需要将某些类的新闻稿推送给相关的用户。
    本题中的集合用整数组表示,因此,需要规定同一数组中的元素各不相同(集合中的元素是各不相同的)。题中,整数组 A[1:m] 阳 B[l:n]分别存储了集合 A 和 B 的元素。流程图的目标是将 A 、B 中相同的元素存放入数组C[ 1:s]  (共s 个元素),并将 A 、B 中 的所有元素(相同元素只取一次)存放入数组  D[1:t]   (共t 个元素),最后再计算集合 A 和 B 相似度的。
    流程图中的第一步显然是将数组 A 中的全部元素放入数组 D 中。随后,只需要对数 组 B 中的每个元素进行判断,凡与数组 A 中某个元素相同时,就将其存入数组 C;  否则就续存入数组 D (注意,数组 D 中已有 m 个元素)。这需要对 j (遍历数组 B) 与 i (遍历数组 A) 进行两重循环。判断框 B[j]=A[i]f lG立时, B[j]应存入数组 C; 否则应继续 i 循环,直到循环结束仍没有相等情况出现时, j 先应将 B[j]存入数组 D。存入数组 C 之前, 需要将其下标 s 增 1; 存入数组 D 之前,需要将其下标 t 增 1。因此,初始时,应当给j 赋 0,使数组C 的存数从C[1]开始。从而,()处应填 s,(3)处应填c[s]。而数组D 是在已有 m 个元素后续存,所以,初始时,数 fi D 的下标 t 应当是 m ,续存是从D[m+1] 开始的。因此,   (2)   处应填 t ,(的处应填D[]。
    两重循环结束后,就要计算相似度的,将其赋予 SIM,因此(5) 处应填的。

第 2 题

阅读以下说明和 C   函数,填充函数中的主缺,将解答填入答题纸的对应栏内。
【说明】
下面的函数 sort(int n,int a[])对保存在数在a中的整数序列进行非递减排序。由于该序列中的元素在一定范围内重复取值,因此排序方法是先计算出每个元素出现的次数并记录在数组b中,再从小到大顺序地排列各元素即可得到一个非递减有序序列。例如, 对于序列 6,5,6,9,6,4,8,6,5.  其元素在整数区间 [4,9]内取值,因此使数组元素 b[0] ~b[5]的下标。0~5分别对应数值4~9. 顺序地扫描序列的每一个元素并累计其出现的次数,即将 4的个数记入b[0],5的个数记b[1],依此类推,9的个数记入b[5]最后依次判断数组b的每个元素值,并将相应个数的数值顺序地写入结果序列即可。
对于上例,所得数组 b 的各个元素值如下:

那么在输出序列中写入 1 个 4、2个 5、4个 6、1 个 8、1 个 9,即得4,5,5,6,6,6,6,8,9,从而完成排序处理。

【C 函数】
void sort(int n ,int a[ ])
{    int  b;
     int i ,k ,number;
     int minimum  = a[0] , maximum = a[0];
     /
minimum 和 maximum 分别表示数组a的最小、最大元素值/

     for(i=1;i<n;i++){
         if(  (1) ) minimum=a[j];
         else
             if( (2) ) maximum=a[i];
     }

     number = maximum - minimum + 1;
     if  (number<=1)   return;
      b =  (int
)calloc (number ,sizeof(int)) ;

     if (!b) return;

     for(i=0;i<n;i++){  /*      计算数组a元素值出现的次数并计入数组b */
          k=a[i]-minimum; ++b[k];
}
/*按次序在数组 a 中写入排好的序列*/
     i=(3)  ;
     for( k=0;  k<number;  k++  )
           for(;  (4)   ; --b[k]   )
                 a [i++]  = minimum  +(5);
}

答案与解析

  • 试题难度:较难
  • 知识点:C程序设计>C程序设计
  • 试题答案:(1) a[i]<minimum ,或a[i]<= minimum ,或其等价形式
    (2) a[i]>maximum ,或a[i]>= maximum ,或其等价形式
    (3) 0
    (4)b[k] ,或b[k]>0 ,或b[k]!=0 ,或其等价形式
    (5)k
  • 试题解析:本题考查 C 程序的基本语法和运算逻辑。 首先应认真分析题目中的说明,然后确定代码结构和各变量的作用。
    空(1)和 (2)所在 for 语句的功能是求出数组 a 中的最小元素 minimum 和最大元素 maxlmum 。在设置了minimum 和 maximum的初始值后,空(1)处的判断条件是只要目前的元素 a[i]小于 minimum ,就需要更新minimum ,反之,空(2)处的判断条件是只要目前的元素 a[i]大于 maximum ,就需    更新maximum ,因此空(1)处应填入 a[i]<minimum 或其等价方式,空 (2)处应填入 a[i] >maximum 或其等价方式。 minimum 和 maximum 的作用是要确定计数数组 b 的大小。
    根据题目中的描述,序列中的每个元素 a[i]都对应到计数数组 b[]的一个元素 b[k] 对应方式为: k = a[i] -minimum ,其中minimum 是数组 a 中的最小元素,显然在计数时, 一个数值出现一次,就在对应的 b[k] 中累加一次。
    空(3)~(5)所在的语句组是产生排序后的序列,重新写入数组 a。首先需明确
    变量 i和 k 的作用,根据它们在该语句组中的出现位置, i用于表示数组 a 的元素下标, k 用于表示数组 b 中元素的下标,因此,空(3)处应填入 0 ,使得从数组a 中下标为 0 的数组元素开始。通过循环控制 "for( k=0; k<number; k++)"己经明确数组 b 的下标变化方式,而需要写入数组 a 的元素个数表示在 b[k] 中,所以 “ for(;(4); --b[k])”中空(4)处应填入 "b[k]>0" 或其等价形式。 (由于 b[k] 中记录的是元素 k+ minimum 的出 现次数,所以空(5)处应填入 "k",从而将元素值恢复后再写回去。

第 3 题

阅读以下说明和 C 代码,填充代码中的空缺,将解答填入答题纸的对应栏内。
【说明 1】
下面的函数 countChar(char *text)统计字符串 text 中不同的英文字母数和每个英文字母出现的次数(英文字母不区分大小写)。  


【c代码1】
int countChar( char *text )
{
     int i,sum = 0;   /* sum 保存不同的英文字母数*/
     char *ptr;
     int  c[26]  =  {0}; /*数组c保存每个英文字母出现的次数*/
     /*c[0]记录字母A或a的次数,c[1] 记录字母B或b的次数,依此类推*/
 
         ptr =   (1)   ;/*ptr初始时指向字符串的首字符*/
     while   (*ptr)   {
             if   (   isupper(*ptr)   )
                 c[*ptr  -  'A']++;
             e1se
                if   (   islower(*ptr)   )
                    c[*ptr  - 'a'] ++;
                   (2)     ;  /*指向下一个字符*/
     }
 
     for(i=0;i<26;i++)
             if    (3)    sum++;
         return  sum;
}
【说明2】
将下面C代码2中的空缺补全后运行,使其产生以下输出。
f2:f2:f2:2
f3:f3: 1
【C代码2】
*include  <stdio.h>
int f1 (int  (*f) (int)) ;
int f2 (int) ; 
int f3 (int) ;
 
int main ()
{
     printf("%d\n" ,f1(    (4)   ));
     printf("%d\n" ,f1(    (5)   ));
     return  0;
}
int  f1 ( int  (*f) (int)  )
{
     int  n  = 0;
     /*通过函数指针实现函数调用,以返回值作为循环条件*/
 
while  (    (6)     )  n++;
return   n;
}

int f2(int n)
{
     printf("f2: ");
     return  n*n-4;
}
 
int f3 (int n)
{
     printf("f3: ");
     return  n-1;
} **答案与解析** - 试题难度:较难 - 知识点:C程序设计>C程序设计 - 试题答案:(1)text ,或&text[0] ,或其等价形式
(2)Ptr++ 或 ++ptr,或ptr=ptr+1,或ptr+=1
(3)c [i] ,或(*c+i)
(4) f2
(5) f3
(6)f(n),或(*f)(n)
- 试题解析:
本题考查数据指针、运算逻辑和函数指针的应用。
 首先应认真分析题目中的说明,然后确立代码结构和各变量的作用。
在函数 countChar(char *text)中来统计字符串 text中不同的英文字母数和每个英文字母出现的次数。用来表示计数值的数组元素c[i]需要与英文字母对应起来,方式为 c[0] 记录字母 A 或 a 的次数,c[1]记录字母 B 或 b 的次数,依此类推,因此 i=英文字母-'A' (英文字母为大写)或 i=英文字母-'a' (英文字母为小写)。
数据指针是指向数据的指针变量。数据指针ptr用来表示 text 中的每一个字符,初始时 ptr 指向第一个字符,因此空(1)处应填入"text" 或其等价方式,(2)处的作用 是随循环控制逐个指出 text 中的后续字符,因此空(2)处应填入 "ptr ++"或其等价方式。
显然,若 c[i]的值不为 0则表示字符‘A'+i 或'a'+i 出现了,反之,则表示字符‘A'+i或'a'+i未出现,因此在计算字符种类时只要判断 c[i]是否为 0 即可,因此空(3)处应填入"c[i]"或其等价形式 。
函数指针是指向函数的指针变量。根据代码 2 的声明 "int f1(int (*f)(int)) ";可知调用函数f1时,实参应该是函数名或函数指针,且函数名或函数指针指向的函数应有一个整型参数,返回值为整型,而f2和f3都是符合这种定义类型的函数。
C 代码 2 中,在 main 函数中两次调用了函数f1,分析运行结果可知,是先以f2为实参调用f1,然后以f3为实参调用 f1 ,因此空(4)和(5)分别填入"f2"或"f3"或它们的等价形式,在空(6)处应填入"f(n) "或其等价形式来实现最后对f2和f3的调用。

### 第 4 题

阅读以下说明和C程序,填充程序中的空缺,将解答填入答题纸的对应栏内。
【说明】
正整数n若是其平方数的尾部,则称n为同构数。例如,6是其平方数36的尾部,76是其平方数5776的尾部,6与76都是同构数。下面的程序求解不超过10000的所有同构数。
己知一位的同构数有三个: 1,5,6,到此二位同构数的个位数字只可能是1,5,6这三个数字。依此类推,更高位数同构数的个位数字也只可能是1,5,6 这三个数字。
下面程序的处理思路是:对不超过10000的每一个整数a,判断其个位数字,若为1、5或6,则将a 转换为字符串as,然后对a进行平方运算,并截取其尾部与as长度相等的若干字符形成字符串后与as比较,根据它们相等与否来断定a是否为同构数。

【C 程序】 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int  myitoa(int ,char  *);  /*将整数转换为字符串*/
/* right取得指定字符串尾部长度为length的子串,返回所得子串的首字符指针*/
char  *right(char*,  int  length);
 
int main ()
{
     int a ,t;  int  len;
     char as[10] ,rs[20];
 
     printf("[1 ,10000]内的同构数: \r");
     for(a=1;a<=10000;a++)  {
         t =       1     ;  /*取整数a的个位数字*/
         if (t!=1&& t!=5 && t!=6)  continue;
         len  =  myitoa(a ,as);  /*数a转换为字符串,存入as */
         myitoa(a*a, rs);  /*数a的平方转换为字符串,存入rs */
/*比较字符串as与rs末尾长度为len的子串是否相等*/
     if (   strcmp (as ,    2   )==0   )  /*若相同则是同构数并输出*/
         printf("%s的平方为%s\n" ,as,rs);
   }
   return 0;
}
int  myitoa(int num ,char *s)  /*将整数num转换为字符串存入s */
{
int i ,n  =  0;
   char ch;
 
/*从个位数开始,取num的每一位数字转换成字符后放入s[] */
   while  (num)   {
        s[n++]  = 3  + '0' ;
        num = num/10;
   }
   s[n]='\0';
        for(i=0;  i<n/2;  i++)   {  /*将s中的字符串逆置*/
            4    ; s[i] = s[n-i-1]; S [n-i-1] = ch;
}
return  n;  /*返回输入参数num的位数*/
}
char *right(char *ms ,int  length)
/*取字符串ms尾部长度为length的子串,返回所得子串的首字符指针*/
{
     int i;
 
     for( ; *ms; ms++);                /*使ms到达原字符串的尾部*/
     for(  i=0;  i<length;        5       );/*使ms指向所得子串的首部字符*/
     return  ms; 
} **答案与解析** - 试题难度:较难 - 知识点:C程序设计>C程序设计 - 试题答案:

(1)a%10,或其等价形式

(2)right(rslen)

(3)num%10 ,或其等价形式

(4)ch = s[i],或ch = *(s+i)

(5) i++ms--,或ms--,i++,或其等价形式 - 试题解析:本题考查C语言语法、数据指针和运算逻辑的应用。首先应认真分析题目中的说明,然后确是代码结构和各变量的作用。 根据题目中的叙述,同构数的个位数为1、5 或 6,因此,对于不超过10000的每个整数,应先获取其个位数字,因此空(1)处应填入"a %10"或其等价形式,从而可以先过滤掉不可能是同构数的数。
根据代码中的注释,通过以下运算后,得到由a中数值转换所得的字符串as,以及a的平方所得数值转换得到的字符串rs,此后通过字符串比较运算来判断是否为同构数。 
len = myitoa(a ,as); /*数a转换为字符串,存入as*/
myitoa(a*a ,rs); /*数a的平方转换为字符串,存入rs*/
函数myitoa(int num,char划的功能是将整数num转换为字符s,这就需要将整数num的每个数字分离出来,通常通过整除取余运算实现,即以下代码所实现的。
while (num) (/*从个位数开始,取num的每一位数字转换为字符后放入s[] */
            s[n++] =   (3)  +   '0';
            num  =  num/10;
}
        s[n]='\0';
其中,空(3)处应填入"num%10" 或其等价形式。
函数right(char*ms,int length)取字符串ms尾部长度为lenth的子串,返回所得子串的首字符指针。该函数的处理思路是先技到ms中字符串的结尾,然后倒着数出length个字符,从而得到所需字符串的首字符指计。空(5)处应填入"i++,ms--” 或其等价形式。
另一个更简便的方式是在得到ms的结尾指针后,再减去length即可,即最后返回ms-lenth即可。 ### 第 5 题   

阅读以下说明和C++代码,填充程序中的空缺,将解答填入答题纸的对应栏内。
【说明】
某应急交通控制系统(TraficControlSystem)在红灯时控制各类车辆 (Vehicle)的通行,其类图如图5-1所示,在紧急状态下应急车辆在红灯时可通行,其余车辆按正常规则通行。
下面的C++代码实现以上设计,请完善其中的空缺。

【C++代码】

     #include <typeinfo>

     #include <iostream>

     using namespace std;

     class Vehicle  {  /*抽象基类,车辆*/
     public:
     virtual void run( )  = 0;
     };
    class Emergency  { /*抽象基类,可在红灯时通行的接口,函数均为纯虚函数*/
    public:
          (1)    =  0;           // isEmergent ( )函数接口

          (2)    = 0;            // runRedLight( ) 函数接口
     };
     class Car: public Vehicle  {
     public:
          ~Car ( ) {   }
          void  run ( ) {  /*代码略*/}
     };
     class Truck: public Vehicle  {
     public:
           ~Truck( ) {    }
          void  run   ( )    {  /*代码略*/  }
     };
     class PoliceCar:  (3)  {
     private:
          bool isEmergency;
     public:
          PoliceCar( )  : Car( ) ,Emergency( ){  this->isEmergency  = false;
     }
     PoliceCar(bool  b)   : Car( ) ,Emergency( ) {  this->isEmergency  =  b;}
          ~policeCar ( )    {  }
          bool  isEmergent ( )   {  return  (4) ;    }
          void   runRedLight( )  {                 /*代码略*/       }
     };
     /*类Ambulance、 FireEngine 实现代码略*/
     class  TraficControlSystern  {  /*交通控制类*/
     private:
         Vehicle* v[24};  int nurnVeh:cles;  /*在构造函数中设置初始值为0*/
     public:
         void  control() {  //控制在紧急情况下应急车辆红灯通行,其他情况按常规通行
             for  (int  i =  0;  i <  numVehicles ;  i++)   {
                  Emergency * ev = dynamic_cast<Emergency*>(v[i]);
                  if (ev  != 0)          (5)  ->runRedLight () ;
                  else                    (6)  ->run () ;
              }
      }
      void  add(Vehicle * vehicle)    {  v[numVehicles++]   = vehicle;
                                       / *添加车辆./
      void shutDown()  {  for  (int i = 0;  i <  numVehicles;  i++)  {  delete    
      v[i];  }       }
    } ;
    int main( )  {
            TraficControlSystern. tcs = new TraficControlSystern;
            tcs->add(new  Car( ));  tcs->add(new   PoliceCar( ));
         tcs->add(new Ambulance( ));tcs->add(new Ambulance(true));
       tcs->add(new  FireEngine(true));  tcs->add(new  FireEngine( ));
       tcs->add(new  Truck( ));
       tcs->control( );  tcs->shutDown( );
           delete  tcs;
       } **答案与解析** - 试题难度:较难 - 知识点:C++程序设计>C++程序设计 - 试题答案:(1) virtual bool isEmergent() 
(2)virtual void runRedLight()
(3) public Car,public Emergency
(4)this->isEmergency
(5) ev      
(6)v[i]
- 试题解析:本题考查 C++语言程序设计的能力,涉及类、对象、函数的定义和相关操作。要求 考生根据给出的案例和执行过程说明,认;王阅读理清程序思路,然后完成题目。
根据题目描述,以交通控制系统(TraficControlSystem)为背景,本题目中涉及的各类车辆和是否应急状态下在红灯时的通行情况。根据说明进行设计,题目给出了类图(图5-1类图所示)。
图中父类Vehicle代表交通工具,设计为抽象类,包含一个方法: run(),表示行驶某一个具体的交通工具对象,行驶的方法由具体子类型完成,所以Vehicle的run()为一个纯虚函数:
virtual void run()  =  0;
Car和Truck都继承自Vehicle的两个子类型,所以它们都继承了Vehicle的run()方法,各自行驶方式有所不同,所以都覆盖了vehicle的run()方法,并加以实现:
void  run () {/*代码略*/}
Car的两个子类型PoliceCar和Ambulance都继承自Car,从而PoliceCar和Ambu1ance也都继承了Car中的run()方法。Truck的子类FireEngine也继承了Truck中的run()方法。
图中接口Emergency在C++中采用抽象茬类的方法实现,其中约定红灯时通行的相关接口函数为: isEmergent()和runRedLight() ,均为纯虚函数,原型中=0表示纯虚函数,实现由子类完成:
virtual bool isEmergent() = 0;
virtual void runRedLight()  = 0;
isEmergent()函数接口约定应急车辆返回自身紧急情况状态,用bool类型的isEmergency 表示: this->isEmergency,其值在紧急情况下为bool值true ,非紧急情况下为bool值 false。runRedLight()函数接口约定应急车辆在红灯时如何通行(isEmergency为剧。则通行,isEmergency为false,和博通车辆一样通行)。 Emergency的子类有PoliceCar 、Abmulance和FireEngine,所以在这三个类中都要实现Emergency中定义的纯虚函数接口。
交通控制类TraficControlSystem对运轩的交通工具进行控制,所有交通工具用Vehicle数组v表示; numVehicles表示交通工具数量; control函数进行控制在紧急情况下应急车辆红灯通行,其他情况按常规通行; add()表示有车辆加入系统,shutDown()在系统关闭时清除每个对象数组元素: delete v[];。Vehicle的子类具体类型有Car、Truck、PoliceCar 、Abmulance和FireEngine,所以飞口数组中对象有这些类型的对象加入v[]时会自动向上转型成为Vehicle类型,而实现了Emergency接口的应急车辆有runRedLight()函数,其他 Car和Truck只有run()函数。因此,用for循环对每个v[i],判定是否是Emergency类型,即是否继承了Emergency ,调用时动态绑定每个数组元素的实际类型,需要通过动态类型转换:
Emergency * ev = dynamic_cast<Emergency*>(v[i]);
 
如果转换成功,说明是Emergency的子类,实现runRedLight(),可以调用runeRdLight(), 否则调用 run():
if (ev  !=  0)         ev ->runRedLigh '. ();
    else v [i]->run () ;
主控逻辑代码在main函数中实现。初始化TraficControlSystem,用tcs表示,调用tcs的add()函数添加具体的交通工具,这里告自动向上转型成为Vehicle类型,调用control()对各车辆进行控制,调用shutDown()系统关闭,使用完数组对象之后,需要用delete操作进行释放对象,即deletetcs;
因此,空(1)和空(2)需要定义纯盘函数isEmergency()和runRedLight(),原型中=0题目代码中己经给出,所以空(1)和空(2)分别为"virtual bool isEmergent()" 和"virtual void runRedLight()";空(3)需要继承Car和Emergency,即"public Car,public Emergency"; 空(4)要返回应急车辆对象的状态,即"this->isEmergency";空(5)处动态类型转换成功的对象ev; 空(6)处为普通车辆对象v[i]。 ### 第 6 题

阅读以下说明和Java代码,填充程序中的空缺,将解答填入答题纸的对应栏内。
【说明】
某应急交通控制系统(TraficControlSystem)在红灯时控制各类车辆 (Vehicle)的通行,其类图如图6-1所示,在紧急状态下应急车辆在红灯时可通行,其余车辆按正常规则通行。

下面的Java代码实现以上设计,请完善其中的空缺。

【Java 代码 】
abstract class Vehicle {
        public Vehicle( ) { }
        abstract  void  run( );
};
interface  Emergency   {
             (1)     ;
             (2)     ;
};
class  Car  extends  Vehicle   {
         public  Car( )   {        )
         void  run ( ) {   /代码略/    }
};
class  Truck  extends  Vehicle  {
          public  Truck( )   { }
          void  run   ( ) {        /代码略/    }
};
 
class PoliceCar     (3)     {
         boolean  isEmergency  =  false;
         public  PoliceCar()    {    }
         public   PoliceCar(boolean   b) {   this.isEmergency=b;   }
         public   boolean   isEmergent( ) { return     ( 4 )   ;    }
         public  void  runRedLight( )  {    /代码略/  }
};
/类Ambulance 、 FireEngine  实现代码略/
public    class   TraficControlSystem     { /交通控制类/
         private  Vehicle[ ]  v  =  new  Vehicle[24];
         int  numVehicles;
         public  void control( )  {
               for  (int  i = 0;  i <  numVehicles;  i++)  {
                        if  (v[i]  instanceof  EmErgency  &&   ((Emergency)v[i]).
                        isEmergent())  {
                           (     5   ) .runRedLigh   (   );
                         }    else
                           ( 6 )  .run ( ) ;
                }
         }    
                void  add(Vehicle  vehicle)   {  v[numVehicles++]  = vehiclei} /添加车辆/
                void   shutDown()    {   /代码略 /}
               
                public  static void  main (Str :.ng [ ]  args)   {
                         TraficControlSystem    tcs  =  new   TraficControlSystem();
                         tcs.add(new     Car()};
                         tcs.add(new  PoliceCar();
                         tcs.add(new  Ambulance();
                         tcs.add(new   Ambulance(t:ue));
                         tcs.add(new FireEngine( :rue));
                         tcs.add(new Truck());
                         tcs.add(new FireEngine( );
                         tcs.control();
                         tcs.shutDown();
         }
}

答案与解析

  • 试题难度:较难
  • 知识点:Java程序设计>Java程序设计案例
  • 试题答案:(1) boolean isEmergent()
    (2) void runRedLight()
    (3)extends Car implements Emergency
    (4) this.isEmergency
    (5) (Emergency)v[i]
    (6) v[i]
  • 试题解析:本题考查Java语言程序设计的能力,涉及类、对象、方法的定义和相关操作。要求考生根据给出的案例和执行过程说明,认真阅读理清程序思路,然后完成题目。
    根据题目说明,以交通控制系统 (Tn .ficControlSystem) 为背景,本题目中涉及的各类车辆和是否应急状态下在红灯时的通行情况。根据说明进行设计,题目给出了类图(图6-1 类图所示)。
    图中父类Vehicle ,代表交通工具,设计为抽象类。在Java用abstract 关键字表示, 表示行驶某一个具体的交通工具。 Vehiclt  包含一个抽象方法: run(),方法后没有实现, 直接用;来表示抽象方法,表示行驶的方法由具体子类型完成,所以Vehicle的 run()为一 个抽象方法:
    abstract void run();
    Car和Truck 都继承自 Vehicle 的两个子类型,所以他们都继承了Vehicle的 run()方法,各自行驶方式有所不同,所以都覆盖了 Vehicle  的 run()方法,并加以实现:
    void  run () U代码略/}
    Car的两个子类型 PoliceCar 和Ambuance 都继承自 Car ,从而PoliceCar 和Ambulance 也都继承了 Car 中的 run(  )方法。 Truck 的子类 FireEngine 也继承了 Truck 的 run()方法。
    图 6-1 中 Emergency 在 Java 中采用技口实现,其中约定红灯时通行的相关接口为:
    isEmergent()和runRedLight()  。
    isEmergent()接口约定应急车辆返回 11身紧急情况状态,用 bool 类型的 isEmergency
    表示:this.isEmergency  ,其值在紧急情况下为true ,非紧急情况下为fales。runRedLight() 接口约定应急车辆在红灯时如何通行( isEmergency 为 true ,则通行,isEmergency  为 false , 和普通车辆一样通行)。实现  Emergency   的类商 PoliceCar、Abmulance  和 FireEngine ,所以在这三个类中都要实现 Emergency 中定义的接口。在 Java 中,实现接口用 implements 关键字,后面加上所要实现的接口,即:
    . ClassName implements  InterfaceName
    交通控制类 TraficControlSystem   对运俨的交通工具进行控制,所有交通工具用 Vehicle 数组 v 表示; numVehicles 表示交通工具数量; control 函数进行控制在紧急情况 下应急车辆红灯通行,其他情况按常规通行; add()表示有车辆加入系统, shutDown()表 示系统关闭。 Vehicle 的子类具体类型有 Car、Tluck、PoliceCar、Abmulance 和 FireEngine , 所以 v[ ]数组中对象有这些类型的对象,加入 v[]时会自动向上转型成为 Vehicle 类型, Emergency 接口的应急车辆有 runRedLight01.法,其他 Car 和 Truck 只有 run()方法。因 此,用 for  循环中对每个 v[i] ,判定是否是Emergency  类型的实例,即是否实现了 Emergency。Java 中判断一个对象是否是某个类型的实例用 instanceof 关键字。即: v[i] instanceof    Emergency ,如果是,说明是应急车辆,接着判定应急车辆的状态,在判定之 前先要将应急车辆进行向下转型, Java 中向下转型直接在对象前加上用括号括起来的转 换的目标类型即可,即:    ((Emergency)vl[i]).isEmergent(),  如果判定为真,执行 runRedLight() ,判定不成功,则调用run()  ,问用时动态绑定每个数组元素的实际类型, 需要通过动态类型转换并调用runR edLight():
    if   (v[i]  instanceof  Emergency  && ((Emergency)v[i)) .isEmergent())   { ((Emergency)v[i]) .runRedLight(  );
    )    else
    v [i]->run () ;
    主控逻辑代码在 mam 方法中实现。初始化 TraficControlSystem ,用tcs 表示,调用 tcs 的add()函数添加具体的交通工具,这里会自动向上转型成为Vehicle 类型,调用 control()对各车辆进行控制,调用 shutDown()系统关问。
    因此,空(1)和空(2)需要定义接口sEmergentO和runRedLight() ,题目代码中 己经给出用分号结尾,所以空(1)和空(2)分别为   “bool    isEmergent()”    和 “void runRedLight()”;空(3)需要继承父类 Car 和实现接口 Emergency ,Java 中继承采用extends关键字,即应填入“extends Car implements Emergency ”:空(4)要返回应急车辆对象的状态,即填入“this.isEmergency”;空 (5) 处为动态类型转换后的对象 (Emergency)v[i]; 空 (6)处为普通车辆对象 v[i] 。

results matching ""

    No results matching ""