image

编辑人: 浅唱

calendar2025-06-08

message9

visits1006

2013年11月 程序员 下午题答案及解析

一、问答题

1、阅读以下说明和流程图,填补流程图中的空缺,将解答填入答题纸的对应栏内。
[说明]
两个包含有限个元素的非空集合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。
[流程图]

参考答案:

 

 

s
t
C[s]
D[t]
s/t

 


解析:

本题主要考查了流程图的设计和理解能力。根据题目描述和流程图,需要计算两个非空整数集合的交集和并集,并计算其相似度。

  1. 在流程图中,首先需要将集合A的所有元素存入数组D,因此,(1)处应表示数组C的当前位置,即s。
  2. 接下来,遍历集合B的每个元素,并与集合A进行比较。如果找到相同的元素,则存入数组C;否则,存入数组D的下一个可用位置。因此,(2)处应表示数组D的下一个可用位置,即t。
  3. 当找到相同的元素并存入数组C时,需要填写数组C的当前位置,即C[s]。
  4. 当存入数组D时,需要填写数组D的下一个位置,即D[t]。
  5. 最后,计算交集元素个数与并集元素个数之比,即相似度s/t,并将其赋值给SIM。

所以,填空答案如上所述。

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(______) minimum=a[i]; 
    eiSe 
    if (______) maximum=a[i]; 
    } 
    number=maximum-minimum+1; 
    if(number<=i)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=______; 
    for(k=0; k<number; k++) 
    for(; ______; --b[k] ) 
    a[i++]=minimum+______; 
    }


参考答案:

a[i]<minimum,或a[i]<=minimum,或其等价形式
a[i]>maximum,或a[i]>=maximum,或其等价形式
0
b[k],或b[k]>0,或b[k]!=0,或其等价形式
k


解析:

本题考查C程序的基本语法和运算逻辑。

首先,应认真分析题目中的说明,然后确定代码结构和各变量的作用。

对于空(1)和空(2),所在的for语句的功能是求出数组a中的最小元素maximum和最大元素minimum。在设置了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),是为了初始化变量i的值为0,使得从数组a中下标为0的数组元素开始。对于空(4),由于需要通过循环控制"for(k=0; k<number;k++)",已经明确数组b的下标变化方式,而需要写入数组a的元素个数表示在b[k]中,所以该处应填入b[k] > 0或其等价形式。对于空(5),由于b[k]中记录的是元素k+minimum的出现次数,所以在将元素值恢复后再写回去时,应填入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=______;     /*ptr初始时指向字符串的首字符*/
    while (*ptr) {
    if (isupper(*ptr) )
    c [*ptr-'A']++;
    else
    if (islower(*ptr))
    c[*ptr-'a']++;
    ______;   /*指向下一个字符*/
    }
    for(i=0;i<26; i++)
    if(______)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(______));
    printf("%d\n",f1(______));
    return 0;
    }
    int f1(int(*f)(int))
    {
    int n=0;
    /*通过函数指针实现函数调用,以返回值作为循环条件*/
    while  (______)  n++;
    return n;
    }
    int f2(int n)
    {
    printf("f2:");
    return n*n-4;
    }
    int f3(int n)
    {
    printf("f3:");
    return n-1;
    }


参考答案:

text,或&text[0],或其等价形式
ptr++,或++ptr,或ptr=ptr+1,或ptr+=1
c[i],或*(c+i)
f2
f3
f(n),或(*f)(n)


解析:

本题考查了指针、数组和函数指针在C语言中的应用。

对于countChar函数,首先需要让ptr指向字符串的首字符,因此第一个空可以填写ptr = text; 或 ptr = &text[0]; 等。然后在循环中,需要逐个指向字符串中的字符,因此第二个空可以填写ptr++或++ptr等。最后,判断某个英文字母是否出现过,可以通过查看数组c中对应位置的元素是否为零来实现,因此第三个空填写c[i]。

对于C代码2,首先需要根据函数声明来确定实参应该是何种类型的函数。f1函数的声明为int f1(int(*f)(int)),表示f1需要一个指向接受一个整型参数并返回一个整型的函数的函数指针作为参数。因此,在main函数中调用f1时,需要传入符合这种定义的函数f2和f3作为实参。最后,在f1函数内部,需要通过函数指针调用传入的函数,并传入参数n获取返回值,因此最后一个空可以填写f(n)或(*f)(n)。

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 fen;
    char as[10],rs[20];
    printf("[1,10000]内的同构数:\n");
    for(a=1; a<=10000;a++)    {
    t=______;   /*取整数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,______)==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++]=______+'0';
    num=num/10;
    }
    s[n]='\0';
    for(i=0; i<n/2;i++){    /*将S中的字符串逆置*/
    ______;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;______);    /*使ms指向所得孔串的首部字符*/
    return ms;
    }


参考答案:

 

 

a%10,或其等价形式
right(rs,len)
num%10,或其等价形式
ch=s[i],或ch=*(s+i)
i++,ms--,或ms--,i++,或其等价形式

 


解析:

本题考查对C语言程序的理解与填空能力。根据题目描述,需要填充程序中的空缺部分,以实现求解不超过10000的所有同构数的功能。

对于第一个空(1),因为要获取整数a的个位数字,所以应使用取余运算a%10来获取。

对于第二个空(2),根据程序逻辑,需要比较字符串as与rs末尾长度为len的子串是否相等,所以应调用right函数来获取rs的尾部长度为len的子串,即填right(rs,len)。

对于第三个空(3),在myitoa函数中,要获取num的每一位数字,需要使用取余运算num%10来获取。

第四个空(4)是关于字符串逆置的,需要交换s中的字符以实现逆置,可以填写ch=s[i]; s[i]=s[n-i-1]; s[n-i-1]=ch;这样的操作来交换字符。

最后一个空(5)是关于right函数中移动指针的,要使得ms指向所得子串的首部字符,可以填写ms–或者ms -= length或者ms = ms - length等表达式来实现指针的逆向移动,同时配合i++来逐步移动指针到正确的位置。

5、 

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

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

[C++代码]
#include<typeinfo>
#include<iostream>
using namespace std;
class Vehicle {/*抽象基类,车辆*/
public:
virtual void run()=0;
};
class Emergency {  /*抽象基类,可在红灯时通行的接口,函数均为纯虚函数*/
public:
______=0;    //isEmergent()函数接口
______=0;    //runRedLight()函数接口
};
clasS Car:public Vehicle{
public:
~Car(){}
void run(){/*代码略*/  )
);
class Truck:public Vehicle{
public:
~Truck(){}
void run(){  /*代码略*/  }
);
class PoliceCar:______ {
private:
bool isEmergency;
public:
PoliceCar():Car(),Emergency() { this->isEmergency=false;
}
PoliceCar(bool b):Car(),Emergency()  {this->isEmergency=b;}
~P0liceCar(){    }
bool isEmergent(){    return ______}
void runRedLight()  {    /*代码略*/    }
);
/*类Ambulance、FireEngine实现代码略*/
class TraficControlsystem {  /*交通控制类*/
private:
Vehicle*v[24];    int numVehicles;/*在构造函数中设置初始值为0*/
public:
void control(){  //控制在紧急情况下应急车辆红灯通行,其他情况按常规通行
for(int i=0;i<numVehicles; i++){
Emergency *ev=dynamic_cast<Emergency*>(v[i]);
if(ev !=0)  ______->runRedLight();
else ______->run();
}
}
void add(Vehicle*vehicle) { v[numVehicles++] =vehicle; }
/*添加车辆*/
void shutDown() {for(int i=0;  i<numVehicles; i++) { delete v[i];}  }
};
int main(){
TraficControlSystem*tcs=new  TraficControlSystem;
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->contr01();tcs->ShutDown();
delete tcs;
}

 

参考答案:

 

 

virtual bool isEmergent()
virtual void nmRedLight()
public Car, public Emergency
this->isEmergency
ev
v[i]

 

解析:

根据题目描述和类图设计,填充C++代码中的空缺如下:

  1. 在Emergency类的定义中,isEmergent()和runRedLight()是纯虚函数,因此填写为:
virtual bool isEmergent() = 0;
virtual void runRedLight() = 0;
  1. PoliceCar类继承自Car和Emergency,因此填写为:
public Car, public Emergency
  1. 在PoliceCar类的isEmergent()函数中,返回对象的状态,即this->isEmergency,因此填写为:
this->isEmergency
  1. 在TraficControlSystem类的control()函数中,动态转换成功的对象ev可以调用runRedLight(),否则调用v[i]->run(),因此空(5)和空(6)处分别填写为:
ev->runRedLight();
v[i]->run();

6、 

阅读以下说明和Java代码,填充程序中的空缺,将解答填入答题纸的对应栏内。

[说明]
某应急交通控制系统(TraficControlSystem)在红灯时控制各类车辆(Vehicle)的通行,其类图如下图所示,在紧急状态下应急车辆在红灯时可通行,其余车辆按正常规则通行。

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

[Java代码]
abstract class Vehicle{
public Vehicle(){  }
abstract void run();
};
interface Emergency{
   ______;
   ______;
};
class Car extends Vehicle{
public Car(){  }
void run(){ /*代码略*/  }
};
Class Truck extends Vehicle{
public Truck(){  }
void run() {  /*代码略*/  }
};
class PoliceCar ______ {
boolean isEmergency= false;
public PoliceCar(){  }
public PoliceCar(boolean b) {this.isEmergency=b;    }
public boolean isEmergent(){  return ______   }
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()){
(______).runRedLight();
}else
______. run();
}
}
void add(Vehicle vehicle){  v[numVehicles++]=vehicle;}/*添加车辆*/
void shutDown(){/*代码略*/}
public static void main(String[]args){
TraficC0ntrolSystem tcs=new TraficControlSystem();
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 Truck());
tcs.add(new FireEngine());
tcs.control();
tcs.shutDown();
}
}

参考答案:

 

 

boolean isEmergent()
void runRedLight()
extends Car implements Emergency
this.isEmergency
(Emergency)v[i]
v[i]

喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:2013年11月 程序员 下午题答案及解析

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share