C++ 应用题专项[C++ 进阶篇应用题模块。]

矩阵

有矩阵基类 MatrixBase 、矩阵类 Matrix 和单位阵 UnitMatrix 的定义及主函数 main ,请在横线处填写适当的代码并删除横线,以实现上述类定义,使此程序的正确输出结果为:

1 2 3 4 5
2 3 4 5 6
3 4 5 6 7

1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include<iostream>
using namespace std;
//矩阵基础类,一个抽象类
class MatrixBase{   
  int rows, cols;
public:
  MatrixBase(int rows, int cols): rows(rows), cols(cols){}
  int getRows()const{ return rows; }    //矩阵行数
  int getCols()const{ return cols; }    //矩阵列数
  virtual double getElement(int r, int c)const=0; //取第i个元素的值
  void show()const{   //分行显示矩阵中所有元素
    for(int i=0; i<rows; i++){
      cout<<endl;
      for(int j=0; j<cols; j++)
      //**********found**********
      cout<<____________________________<<" ";  
    }
  }
};
//矩阵类
class Matrix: public MatrixBase{  
  double *val;
public:
  //**********found**********
  Matrix(int rows, int cols, double m[]=NULL): ________________________{
    //**********found**********
    val=___________________________;
    for(int i=0; i<rows*cols; i++)
      val[i]=(m==NULL? 0.0 : m[i]);
  }
  ~Matrix(){ delete []val; } 
  double getElement(int r, int c)const{ return val[r*getCols()+c]; }
};
//单位阵(主对角线元素都是1,其余元数都是0的方阵)类
class UnitMatrix: public MatrixBase{  
public:
  UnitMatrix(int rows): MatrixBase(rows, rows){} //单位阵行数列数相同
  double getElement(int r, int c)const{
    //**********found**********
    if(____________) return 1.0;
    return 0.0; 
  }
};

int main(){
  MatrixBase *m;
  double d[][1]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};

  m=new Matrix(3,5,(double *)d);
  m->show();
  delete m;
  cout<<endl;
  m=new UnitMatrix(6);
  m->show();
  delete m;
  return 0;
}

根据题意可得,第一空是要对整个矩阵的元素进行输出,因此这里的输出目标是行为 i ,列为 j 的元素,根据上面的两个嵌套循环可推断,输出矩阵元素主要是通过纯虚函数 getElement() 实现的,因此该空为:

getElement(i,j)

第二空考察的是初始化列表的使用,派生类的构造函数对基类初始化需要使用初始化列表,因此第二空为:

MatrixBase(rows,cols)

第三空考察的是动态数组,由后面的析构函数可以看出,val 是 double 形指针,并在堆区开辟了数据,并且创建的数据空间大小应该容纳下所有数据元素,行×列的值即为所有成员的个数,因此该空为:

new double [rows*cols]

第四空考察的是对题意的理解及函数掌握,单位矩阵是对角线处元素都为 1 ,否则输出 0 ,下文已经给出了 0 的输出语句,通过观察我们可以得到,单位矩阵的行列相等时,就是其对角线元素所占的位置,因此此空为:

r == c

完成填空后输出结果如下,满足题意:

图片[1] - C++ 应用题专项 - NCER - 岁有余生
输出结果

整数型数组转换为整数

请编写一个函数 int Invert(char*str),其作用是将一个表示整数的字符串转换为相应整数。注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include <iostream>
#include <cstring>
using namespace std;
int Invert(char *str)
{
//**********found***********
  _____________________;
  while(*str!='\0')
  {
//**********found***********
    int digital=___________;
    num=num*10+digital;
//**********found***********
    _________________
  }
  return num;
}

int main()
{
  char *str=new char[10];
  cout<<"Please input the integer string:";
  cin>>str;
  cout<<Invert(str)<<endl;
  return 0;
}

由题意可得,下面的 num 未定义且其在 while 中作为循环的累加值使用,因此第一个空需要对 num 进行定义并初始化为 0,因此第一空为:

int num = 0

第二空考察指针及对题意的理解,由题意可得,我们在对数组进行输出时,需要对数组中的所有值进行遍历,并直接对齐进行输出,但数组中的十位数字未必都需要完整赋值,因此数组成可能存在 字符0,因此如果字符中存储的数据为 字符0 时,我们需要也要让他的数组变为 数字0 ,即消除自身,因此第二空为:

 *str- '0'

第三空考察的是 while 循环while 循环中需要有循环继续下一步的条件,这里用对其进行累加,因此要对 str 中的所有值进行遍历,第三空为:

str++

运行后输入 2 ,结果如下,与题意一致:

图片[2] - C++ 应用题专项 - NCER - 岁有余生
输出结果

三角形面积

该工程中包含一个程序文件 main.cpp 其中有坐标点类 point、线段点类 Line 和三角形类 Triangle 和主函数 main 的定义,程序中两点间的距离公式是通过:\( d=\sqrt{\left(\left(x_1-x_2\right)^2+\left(y_1-y_2\right)^2\right)}\) 实现的,三角形的面积计算公式是通过:\( f=\sqrt{s\left(s-a\right)\left(s-b\right)\left(s-c\right)}\) 实现的,其中 \(s= \frac{a+b+c}{2} \) 。注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。


#include<iostream>
#include<cmath>
using namespace std;

class Point{  //坐标点类
public:
  const double x,y;
  Point(double x=0.0, double y=0.0): x(x),y(y){}
  //**********found**********
  double distanceTo(_____________)const{   //到指定点的距离
    return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)) ;
  }
};

class Line{  //线段类
public:
  const Point p1,p2;  //线段的两个端点  

  //**********found**********
  Line(Point p1, Point p2): _______________________{}
  double length()const{ return p1.distanceTo(p2); }  //线段的长度
};

class Triangle{   //三角形类
public:
  const Point p1,p2,p3;    //三角形的三个顶点

//**********found**********
  Triangle(_________________________): p1(p1),p2(p2),p3(p3){}
  double length1()const{ //边p1,p2的长度
    return Line(p1, p2).length() ; 
  }
  double length2()const{ //边p2,p3的长度
    return Line(p2, p3).length(); 
  }
  double length3()const{ //边p3,p1的长度
    return Line(p3, p1).length(); 
  }
  double area()const{   //三角形面积
    //**********found**********
    double s=__________________________________________;
    return sqrt(s*(s-length1())*(s-length2())*(s-length3())); 
  }
};

int main(){
  Triangle r(Point(0.0, 8.0), Point(5.0, 0.0), Point(0.0, 0.0));
  cout<<"Side 1: "<<r.length1()<<endl;
  cout<<"Side 2: "<<r.length2()<<endl;
  cout<<"Side 3: "<<r.length3()<<endl;
  cout<<"area: "<<r.area()<<endl;
  return 0;
}

第一空考察的是 const 关键字及函数形参,由后一行和题意可以得出,该空需要传入一个 Point 类的对象,其对象形参名为 p ,为了不改变值且必须满足22行中实参的传入类型(为常函数),故需要在前面加上 const

const Point& p

第二空考察的是初始化列表,由前面设置的参数可得第二空需要对该值进行初始化:

p(p1),p(p2)

第三空考察的是对构造函数的掌握,从后面初始化列表的语句可以得知该构造函数需要对其个私有成员进行初始化,且从27行可以得知三个变量为 Point 类,故填:

Point p1,Point p2, Point p3

第四空考察的是对成员函数的掌握及对题意的理解,根据题干可知 \(s= \frac{a+b+c}{2} \) 且代码的 31、34、37行所定义的函数对三条边的值进行了计算,因此填:

(length1()+length2()+length3())/2

运行后结果如下,与题意一致:

图片[3] - C++ 应用题专项 - NCER - 岁有余生
输出结果

零向量类

有向量基类 VestorBase 、向量类 Vector 和零向量类 ZeroVector 的定义,请在横线处填写适当的代码并删除横线,以实现上述类定义。该程序正确输出结果应为:

(1,2,3,4,5)
(0,0,0,0,0,0)

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include<iostream>
using namespace std;

class VectorBase{     //向量基类,一个抽象类
  int len;
public:
  VectorBase(int len): len(len){}
  int length()const{ return len; }    //向量长度,即向量中元素的个数
  virtual double getElement(int i)const=0; //取第i个元素的值
  virtual double sum()const=0;  //求所有元素的和
  void show()const{   //显示向量中所有元素
    cout<<"(";
    for(int i=0; i<length()-1; i++) cout<<getElement(i)<<", ";
    //**********found**********
    cout<<____________________________<<")"<<endl;//显示最后一个元素
  }
};

class Vector: public VectorBase{  //向量类
  double *val;
public:
  Vector(int len, double v[]=NULL): VectorBase(len){
    val=new double[len];
    for(int i=0; i<len; i++) val[i]=(v==NULL? 0.0 : v[i] );
  }
  //**********found**********
  ~Vector(){ ___________________________; }
  double getElement(int index)const{ return val[index]; }
  double sum()const{
    double s=0.0;
    //**********found**********
    for(int i=0; i<length(); i++) _____________________;
    return s;
  }
};

class ZeroVector: public VectorBase{  //零向量类
public:
  ZeroVector(int len): VectorBase(len){}
  //**********found**********
  double getElement(int index)const{ ____________________________; }
  double sum()const{ return 0.0; }
};

int main(){
  VectorBase *v;
  double d[]={1,2,3,4,5};

  v=new Vector(5,d);
  v->show();
  delete v;
  v=new ZeroVector(6);
  v->show();
  delete v;
  return 0;
}

第一空由题意可知,结果是输出数组中的最后一个数字,前面有纯虚函数 virtual double getElment(int i)const = 0 并且已注释是取数组中第 i 个元素的值,因此我们可以直接使用该函数输出最后一个元素,这就需要调用第8行中的数组长度函数 length() ,但要注意数组中的角标需要减 1 :

getElement(length()-1)

第二空考察的是析构函数的使用,23行代码中产生了一个堆区空间 val 因此我们需要在析构函数中释放该空间:

delete[]val

第三空考察的是对纯虚函数及函数的了解,从第10行的注释中我们可以得知纯虚函数 sum 是用于对该数组求和,因此在向量类中需要对该函数进行重写,因此该函数是实现累加的过程,故填:

s += val[i]

第四空考察的是对题意的理解,由题意可以得知,零向量类的取值永远为 0 ,且函数 getElement() 是用于返回数组中第 index 数的值,故填:

return 0

运行后结果如下,与题意一致:

图片[4] - C++ 应用题专项 - NCER - 岁有余生
输出结果

菱形继承

其中定义了 vehicle 类,并派生出了 motorcar 类和 bicycle 类,然后以 motorcar 和 bicycke 作为基类,再派生出 motorcycle 类。要求将 vehicle 作为虚基类,避免二义性问题,请在横线处填写适当的代码并删除横线,以实现上述类定义。该程序正确输出结果应为:

80
150
100
1

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include <iostream>
using namespace std;

class vehicle
{
private:
  int MaxSpeed;
  int Weight;
public:
  //**********found**********
  vehicle(int maxspeed, int weight):_______________________________________
  ~vehicle(){}; 
  int getMaxSpeed() { return MaxSpeed; }
  int getWeight() { return  Weight; }
};

//**********found**********
class bicycle : _________  public vehicle
{ 
private:
  int Height;
public:
  bicycle(int maxspeed, int weight, int height):vehicle(maxspeed, weight),Height(height){}
  int getHeight(){ return Height; };
};
 
//**********found**********
class motorcar : __________ public vehicle
{ 
private:
  int SeatNum;
public:
  motorcar(int maxspeed, int weight, int seatnum):vehicle(maxspeed, weight),SeatNum(seatnum){}
  int getSeatNum(){ return SeatNum; };
};

//**********found**********
class motorcycle :  _______________________________
{ 
public:
  motorcycle(int maxspeed, int weight, int height):
      vehicle(maxspeed, weight),bicycle(maxspeed, weight,height),motorcar(maxspeed, weight, 1){}
};

void main()
{
  motorcycle a(80,150,100);
  cout<<a.getMaxSpeed()<<endl;
  cout<<a.getWeight()<<endl;  
  cout<<a.getHeight()<<endl;  
  cout<<a.getSeatNum()<<endl;  
}

第一空考察的是初始化列表,注意不要遗漏初始化列表后面的函数体,因此该空应填:

MaxSpeed(maxspeed),Weight(weight){}

第二空、第三空考察的是对派生类和继承的掌握,由题意可知,vehicle 为虚基类,因此需要在继承的类名前加上虚函数关键字 virtual

virtual

第四空考察的是多继承的写法,由题意可知这是一个菱形继承,因此需要将 vehicle 的两个派生类以公有方式继承:

public bicycle,public motor

运行后结果如下,与题意一致:

图片[5] - C++ 应用题专项 - NCER - 岁有余生
输出结果

人员排序

该工程包含一个程序文件 main.cpp ,其中有日期类 Date 、 人员类 Person 以及排序函数 SortByName 和主函数 main 的定义请在横线处填写适当的代码并删除横线,以实现上述类定义。该程序正确输出结果应为:

按姓名排序
排序前:
张三 男 出生日期:1978年4月20日
王五 女 出生日期:1965年8月3日
杨六 女 出生日期:1965年9月5日
李四 男 出生日期:1973年5月30日

排序后:
李四 男 出生日期:1973年5月30日
王五 女 出生日期:1965年8月3日
杨六 女 出生日期:1965年9月5日
张三 男 出生日期:1978年4月20日

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include<iostream>
using namespace std;

class Date{            // 日期类
  int year,month,day;  // 年、月、日
public:    
  Date(int year, int month, int day):year(year),month(month),day(day){}
  int getYear()const{ return year; }
  int getMonth()const{ return month; }
  int getDay()const{ return day; }
};

class Person{       // 人员类
  char name[14];    // 姓名
  bool is_male;     // 性别,为 true 时表示男性
  Date birth_date;  // 出生日期
public:
  Person(char *name, bool is_male, Date birth_date)
    //**********found**********
    :_____________________________________________________
    
  {
    strcpy(this->name, name);
  }
  const char *getName()const{ return name; }

  bool isMale()const{ return is_male; }

  Date getBirthdate()const{ return birth_date; }

  //利用strcmp()函数比较姓名,返回一个正数、0 或负数,分别表示大于、等于、小于
  int compareName(const Person &p)const{ 
    //**********found**********
    _______________________________________
  }

  void show(){
    cout<<endl;
    cout<<name<<' '<<(is_male? "男" : "女")<<' '<<"出生日期:"
      <<birth_date.getYear()<<"年"       //显示出生年
      //**********found**********
      ____________________________________________  //显示出生月
      <<birth_date.getDay()<<"日";       //显示出生日
  }
};

void sortByName(Person ps[], int size){  //将人员数组按姓名排列为升序
  for(int i=0; i<size-1; i++){         //采用选择排序算法
  int m=i;
  for(int j=i+1; j<size; j++)
    if(ps[j].compareName(ps[m])<0) m=j;
    if(m>i){
      Person p=ps[m];
      ps[m]=ps[i];
      ps[i]=p;
    }
  }
}

int main(){
  Person staff[]={
    Person("张三", true, Date(1978, 4, 20)),
    Person("王五", false, Date(1965,8,3)),
    Person("杨六", false, Date(1965,9,5)),
    Person("李四", true, Date(1973,5,30))
  };

  const int size=sizeof(staff)/sizeof(staff[0]); 
  int i;
  cout<<endl<<"按姓名排序";
  cout<<endl<<"排序前:";
  for(i=0; i<size; i++) staff[i].show();

  sortByName(staff,size);

  cout<<endl<<endl<<"排序后:";
  for(i=0; i<size; i++) staff[i].show();

  cout<<endl;
  return 0;
}

第一空考察函数体的掌握和初始化列表,构造函数需要对所有成员进行初始化,由第23行可知还需要对另外两个变量进初始化,故填:

is_male(is_male), birth_date(birth_date)

第二空考察的是题意理解以及 strcmp() 函数的掌握,由题意可得,利用 strcmp() 函数比较姓名,返回一个正数、0 或负数,分别表示大于、等于、小于,我们知道 strcmp() 本身就会返回值,因此只需要将两个字符串进行对比即可,由25行的getName()函数可以得到姓名,故该空为:

return strcmp(name, p.getName());

第三空考察的是函数调用和题意理解,我们可以根据对年和日的输出推导出月的输出:

<< birth_date.getMonth() << "月" 

输出结果如下,与题意无误:

图片[6] - C++ 应用题专项 - NCER - 岁有余生
输出结果

汽车类

该工程包含一个程序文件 main.cpp ,其中有类 AutiMobile(汽车)及其派生类 Car(小轿车)、Truck(卡车)及主函数 main 的定义,请在横线处填写适当的代码并删除横线,以实现上述类定义。该程序正确输出结果应为:

车牌号:冀 ABC1234  品牌:ForLand  类别:卡车  当前档位:0    最大载重量:12
车牌号:冀 ABC1234  品牌:ForLand  类别:卡车  当前档位:2    最大载重量:12
车牌号:沪 XYZ5678  品牌:QQ  类别:小轿车  当前档位:0  座位数:5
车牌号:沪 XYZ5678  品牌:QQ  类别:小轿车  当前档位:-1  座位数:5

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;

class AutoMobile{      //“汽车”类
  char *brand;         //汽车品牌
  char *number;        //车牌号
  int speed;           //档位:1、2、3、4、5,空档:0,倒档:-1
public:
  AutoMobile(const char *the_brand, const char *the_number): speed(0){
    brand=new char[strlen(the_brand)+1];
    //**********found**********
    __________________________________________;
    //**********found**********
    __________________________________________;
    strcpy(number, the_number);
  }
  ~AutoMobile() { delete[] brand; delete[] number; }
  const char *theBrand()const{ return brand; }      //返回品牌名称
  const char *theNumber()const{ return number; }    //返回车牌号
  int currentSpeed()const{ return speed;}           //返回当前档位
  void changeGearTo(int the_speed){                 //换到指定档位
    if(speed>=-1 && speed<=5)
      speed=the_speed;
  }
  virtual const char *category()const=0;            //类别:卡车、小轿车等
  virtual void show()const{
    cout<<"车牌号:"<<theNumber()
    //**********found**********
        <<"  品牌:"<<______________
        <<"  类别:"<<category()
        <<"  当前档位:"<<currentSpeed();
  }
};
class Car: public AutoMobile{   //“小汽车”类
  int seats;   //座位数
public:
  Car(const char *the_brand, const char *the_number, int the_seats)
    : AutoMobile(the_brand, the_number), seats(the_seats){}
  int numberOfSeat()const{ return seats; }               //返回座位数
  const char *category()const{ return "小轿车"; }        //返回汽车类别
  void show()const{
    AutoMobile::show();
    cout<<"  座位数:"<<numberOfSeat()<<endl;
  }
};

class Truck: public AutoMobile{  //“卡车”类
  int max_load;  //最大载重量
public:
  Truck(const char *the_brand, const char *the_number, int the_max_load)
    : AutoMobile(the_brand, the_number), max_load(the_max_load){}
  int maxLoad()const{ return max_load; }        //返回最大载重量
  //**********found**********
  const char *category()_________________       //返回汽车类别
  void show()const{
    AutoMobile::show();
    cout<<"    最大载重量:"<<maxLoad()<<endl;
  }
};


int main(){
  Truck truck("ForLand","冀 ABC1234",12);
  truck.show();
  truck.changeGearTo(2);
  truck.show();
  Car car("QQ","沪 XYZ5678",5);
  car.show();
  car.changeGearTo(-1);
  car.show();
  cout<<endl;
  return 0;
}

第一、二空考察的是对 strcpy 函数的掌握情况,在第12行代码中,系统给 brand 指针分配了堆区空间,再分别根据17、19行的代码可知,第一第二空是为了完成对 number 及 brand 字符串的赋值,因此我们在看到对分配的空间 + 1 的操作时,就要联想到 strcpy 函数:

    //第一空
    strcpy(brand, the_brand);;
    //第二空
    number = new char[strlen(the_number) + 1];

第三空考察对题意理解和成员函数,已给出注释输出的是品牌名称,我们可以直接调用第20行定义的函数进行输出:

theBrand()

第四种考察的是对纯虚函数的掌握,根据纯虚函数的定义及小汽车类第42行返回的内容,可以得出:

const{ return "卡车"; } 

输出结果如下,与题意无误:

图片[7] - C++ 应用题专项 - NCER - 岁有余生
输出结果

外接矩形

其中类 point(点)、Rectangle(矩形)和 Circle(圆)的定义,在程序所使用的平面坐标系统中,x 轴的正方向是水平向右的,y 轴的正方向是竖直向下的,请在横线处填写适当的代码以实现上述类定义。该程序正确输出结果应为:

-- 圆形 ------------------
圆心 = (3,2)
半径 = 1
面积 = 3.14159

-- 外切矩形 --------------
左上角 = (2,1)
右下角 = (4,3)
面积   = 4

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include <iostream>
#include <cmath>
using namespace std;

// 平面坐标中的点
// 本题坐标系统中,x轴的正方向水平向右,y轴的正方向竖直向下。
class Point {
public:
  Point(double x=0.0, double y=0.0): x_(x), y_(y) { }
  double getX() const { return x_; }
  double getY() const { return y_; }
  void setX(double x) { x_ = x; }
  void setY(double y) { y_ = y; }
private:
  double x_;       // x坐标
  double y_;       // y坐标
};

//  矩形
class Rectangle {
public:
  Rectangle(Point p, int w, int h)
    : point(p), width(w), height(h) {}
        
  double area() const    // 矩形面积
  {
    return width * height;
  }
    
  Point topLeft() const  // 左上角顶点
  {
    return point;
  }
    
  Point bottomRight() const  // 右下角顶点(注:y轴正方向竖直向下)
  {
    //**********found**********
    return Point(___________________________________________);
  }
private:
  Point point;    // 左上角顶点
  double width;   // 水平边长度
  double height;  // 垂直边长度
};

// 圆形
class Circle {
public:
  Circle(Point p, double r) : center(p), radius(r) { }
    
  Rectangle boundingBox() const;  // 外切矩形
    
  double area() const  // 圆形面积
  {
    //**********found**********
    return PI * _______________;
  }
public:
  static const double PI;  // 圆周率
private:
  Point center;   // 圆心
  double radius;  // 半径
};
const double Circle::PI = 3.14159;

Rectangle Circle::boundingBox()    const
{
  //**********found**********
  Point pt(__________________________________________);
    
  int w, h;
  //**********found**********
  w = h = ________________________;
    
  return Rectangle(pt, w, h);
}

int main()
{
  Point p(3, 2);
  Circle c(p, 1);
    
  cout << "-- 圆形 ------------------\n";
  cout << "圆心 = (" << p.getX() << ',' << p.getY() << ")\n";
  cout << "半径 = " << 1 << endl;
  cout << "面积 = " << c.area() << endl << endl;
    
  Rectangle bb = c.boundingBox();
  Point tl = bb.topLeft();
  Point br = bb.bottomRight();
  cout << "-- 外切矩形 --------------\n";
  cout << "左上角 = (" << tl.getX() << ',' << tl.getY() << ")\n";
  cout << "右下角 = (" << br.getX() << ',' << br.getY() << ")\n";
  cout << "面积   = " << bb.area() << endl;    
    
  return 0;
}

第一空考察的是对题意的理解和对函数的掌握,由注释可得,这里返回的是外接矩形右下角的顶点,通过画图分析(或题目中的输出内容)可得,右下角顶点是圆形的圆心坐标分别加上矩形的长和宽,故填:

return Point(point.getX()+ width,point.getY()+height);

第二空考察的是对题意的理解和对函数的掌握,由注释可得,这里返回的是圆形的面积,圆形面积为 2*Π*r ,故该空填:

radius* radius

第三空考察的是对题意的理解和对函数的掌握,这里虽然没有注释,但是通过矩形类中32行代码直接返回该点的坐标可得,这里要求定义的是矩形的左上角顶点,通过画图分析(或题目中的输出内容)可得矩形的左上角顶点为圆形圆心坐标分别减去圆的半径,故填:

center.getX()-radius,center.getY()-radius

第四空考察的是对题意得理解,综上所述,这里得 w 和 h 应为矩形的长和宽,外接的长和宽应该等于圆的直径,故填:

radius*2;

输出结果如下,与题意无误:

图片[8] - C++ 应用题专项 - NCER - 岁有余生
输出结果

输出图形

有类 Graphics(图形)、IsocelesTriangles(等腰三角形)、Parallelogram(平行四边形)和主函数 main 的定义,请在横线处填写适当的代码以实现上述类定义。该程序正确输出结果应为:

6
             *
           * * *
         * * * * *
       * * * * * * *
     * * * * * * * * *
   * * * * * * * * * * *

             * * * * * *
           * * * * * *
         * * * * * *
       * * * * * *
     * * * * * *
   * * * * * *

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

include <iostream>
#include <iomanip>
using namespace std;

class Graphics                    //图形类
{
public:
    Graphics(int e):edges(e) { }
    //**********found**********
    ____________________________
protected:
    int edges;
};

//**********found**********
__________________________________        //等腰三角形类
{
public:
    IsocelesTriangles(int x):Graphics(x) { }
    void Draw();
};

void IsocelesTriangles::Draw()
{
    int i,j;
    if(edges<=0)
        cout<<"errors"<<endl;
    if(edges>0)
    {
        for(i=0;i<edges;i++)
        {
                        //**********found**********
                        _____________________________        //输出前导空格
                cout<<setw(2)<<' ';
                        for(j=0;j<2*i+1;j++)
                                cout<<setw(2)<<'*';
            cout<<endl;
        }
    }
        cout<<endl;
}

class Parallelogram : public Graphics        //平行四边形类
{
public:
    Parallelogram(int x):Graphics(x) { }
    void Draw();
};

void Parallelogram::Draw()
{
    int i,j;
    if(edges<=0)
        cout<<"errors"<<endl;
    if(edges>0)
    {
        for(i=0;i<edges;i++)
        {
            for(j=0;j<edges-i;j++)
                cout<<setw(2)<<' ';
                        //**********found**********
                        _____________________________        //输出每行的*号
                                cout<<setw(2)<<'*';
            cout<<endl;
        }
    }
        cout<<endl;
}

int main()
{
    int e;
    cin>>e;
    Graphics *objs[2];
    objs[0]=new IsocelesTriangles(e);
    objs[1]=new Parallelogram(e);
    for(int i=0;i<2;i++)
        objs[i]->Draw();
    delete objs[0];
    delete objs[1];
    return 0;
}

第一空考察的是纯虚函数,由题意得,图形类是一个基类,等腰三角形类和平行四边形都继承于图形类中,且三个类中都存在 Draw() 函数,因此应该声明基类中的 Draw() 函数为纯虚函数,已实现派生类中的多态,故填:

virtual void Draw() = 0;

第二空考察的是类的继承和声明,由题意可得,此处应为等腰三角形类的声明,并且公共继承了图形类,故填:

class IsocelesTriangles : public Graphics

第三空考察的是 for 循环和对题意的理解,由注释可得,此处用于输出每行的前导空格,我们可以从题目给出得输出内容中推断除,每行得前导空格数量为最大行数减去当前行数,由题意可得最大行数为 edges ,且下一行的代码输出为空格,因此可以推断出需要使用 for 循环来执行,故填:

for (j = 0; j < edges - i; j++)    

第四空考察的是 for 循环和对题意的理解,根据等腰三角形类和注解可以推断出,这里需要填写的是组成平行四边形的 * 号,根据输出内容可以发现,平行四边形中每行的 *号都为固定的最大函数 edges,因此也需要使用 for 循环来执行,故填:

for (j = 0; j < edges; j++) 

输出结果如下,与题意无误:

图片[9] - C++ 应用题专项 - NCER - 岁有余生
输出结果

多项式求值

其中有类 Quadritic 类 Root 以及主函数 main 的定义。一个 Quadritic 对象表示一个 \(a\mathop{{x}}\nolimits^{{2}}+bx+c=0\) 的一元二次多项式。一个 Root 对象用于表示方程 \(a\mathop{{x}}\nolimits^{{2}}+bx+c=0\) 的一组根,它的数据成员 num_ of_ roots 有三种可能的值,即 0 、1 和 2 ,分别表示根的三种情况:无实根、有两个相同的实根和有两个不同的实根。请在程序中的横线处填写适当的代码并删除横线,以实现上述类定义。此程序的正确输出结果应为(注:输出中的X^2表示\(x^2\)):

3X^2+4X+5=0.0无实根
4 5X^2+6X+2=0.0 有两个相同的实根: -0.666667和-0.666667
1.5X^2+2X-3=0.0有两个不同的实根: 0 896805和-2.23014

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;

class Root{                // 一元二次方程的根
public:
  const double x1;         // 第一个根
  const double x2;         // 第二个根
  const int num_of_roots;  // 不同根的数量:0、1 或 2
  //创建一个“无实根”的Root对象
  Root(): x1(0.0), x2(0.0), num_of_roots(0){}
  //创建一个“有两个相同的实根”的Root对象
  Root(double root)
    //**********found**********
    :_______________________________________________{}
   //创建一个“有两个不同的实根”的Root对象
  Root(double root1, double root2)
    : x1(root1), x2(root2), num_of_roots(2){}
  void show()const{            //显示根的信息
    cout<<"\t\t";
    switch(num_of_roots){
      case 0: 
        //**********found**********
        _______________________________
      case 1: 
        cout<<"有两个相同的实根:"<<x1<<" 和 "<<x2; break;
      default:  
        cout<<"有两个不同的实根:"<<x1<<" 和 "<<x2; break;
    }
  }
};

class Quadratic {      // 二次多项式
public:    
  const double a,b,c;  // 分别表示二次项、一次项和常数项等三个系数
  Quadratic(double a, double b, double c)     // 构造函数
  //**********found**********
    :__________________________________{}
  Quadratic(Quadratic& x)              // 拷贝构造函数
    :a(x.a), b(x.b), c(x.c){}
  Quadratic add(Quadratic x)const{     // 求两个多项式的和
    return Quadratic(a+x.a, b+x.b, c+x.c);
  }
  Quadratic sub(Quadratic x)const{     // 求两个多项式的差
    //**********found**********
    ____________________________________________
  }
  double value(double x)const{         // 求二次多项式的值
    return a*x*x+b*x+c;
  }
  Root root()const{                    // 求一元二次方程的根
    double delta=b*b-4*a*c;            // 计算判别式
    if(delta<0.0) return Root();
    if(delta==0.0) return Root(-b/(2*a));
    double sq=sqrt(delta);
    return Root((-b+sq)/(2*a), (-b-sq)/(2*a));
  }
  void show()const{                   // 显示多项式
    cout<<endl
      <<a<<"X^2"<<showpos<<b<<"X"<<c<<noshowpos;
  }
  void showFunction(){                // 显示一元二次方程
    show();
    cout<<"=0.0";
  }
};

int main(){
  Quadratic q1(3.0, 4.0, 5.0), q2(4.5, 6.0, 2.0), q3(q2.sub(q1));
  q1.showFunction();
  q1.root().show();
  q2.showFunction();
  q2.root().show();
  q3.showFunction();
  q3.root().show();
  cout<<endl;
  return 0;
}

第一空考察的是初始化列表,由题意得,创建两个相同的实根,且第9-11行中给出类中具体数据成员的名称,且传入了一个值 root,因此我们需要将该值同时赋给两个根形参,并将根的数量同步为 2 ,故填:

x1(root), x2(root), num_of_roots(2)

第二空考察的是输出语句,由题意得,此处应输出无实根,且不需要填充数据,故填:

cout << "无实根" ; break;

第三空考察的是初始化列表,由题意得将三个不同的系数数值输入到根式使根式实例化即可,故填:

a(a),b(b),c(c)

第四空考察的是对函数的掌握和对题意的理解,由题意得,两个多项式的差就是各个次方的系数相减,故填:

return Quadratic(a - x.a, b - x.b, c - x.c)

输出结果如下,与题意无误:

图片[10] - C++ 应用题专项 - NCER - 岁有余生
输出结果

添加字符串

其中定义了类 Set 和用于测试该类的主函数 main 。类 Set 是一个用于描述字符集合的类,在该字符集合中,元素不能重复(将 'a' 和 'A' 视为不同元素),元素最大个数为 100 。为该类实现一个构造函数 Set(char*s) ,它用一个字符串来构造一个集合对象,当字符串中出现重复字符时,只放入一个字符。此外,还要为该类实现另一个成员函数,InSet(char c) ,用于测试一个字符 c 是否在一个集合中,若在,则返回 true ;否则返回 false 。

请在标有注释 /TODO: 的行中添加适当的代码,将这两个函数补充完整,以实现其功能。

提示:在实现构造函数时,可以调用 InSet 函数来判断一个字符是否已经在集合中。

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include <iostream>
using namespace std;

const int MAXNUM = 100;

class Set {
private:
    int num;            // 元素个数
    char setdata[MAXNUM];        // 字符数组,用于存储集合元素
public:
    Set(char *s);             // 构造函数,用字符串s构造一个集合对象
    bool InSet(char c);        // 判断一个字符c是否在集合中,若在,返回true,否则返回false
    void Print() const;             // 输出集合中所有元素
};

Set::Set(char *s)
{
    num = 0;
    while (*s){
//**********found**********
    if (_______________)         // TODO: 添加代码,测试元素在集合中不存在
//**********found**********
        _________________________;    // TODO: 添加一条语句,加入元素至集合中
        s++;
    }
}

bool Set::InSet(char c)
{
    for (int i = 0; i < num; i++)
//**********found**********
      if (_________________)    // TODO: 添加代码,测试元素c是否与集合中某元素相同
//**********found**********
         ___________________________;        // TODO: 添加一条语句,进行相应处理

    return false;
}

void Set::Print() const
{
    cout << "Set elements: " << endl;
    for(int i = 0; i < num; i++)
        cout << setdata[i] << ' ';
    cout << endl;
}

int main()
{
    char s[MAXNUM];
    cin.getline(s, MAXNUM-1);        // 从标准输入中读入一行
    Set setobj(s);                // 构造对象setobj
    setobj.Print();                // 显示对象setobj中内容
    return 0;
}

第一空考察的是对题意的理解和对 if 函数的使用,由题干得,可以调用 InSet 函数来判断一个字符是否已经在集合中,且 InSet 函数中字符若若在,则返回 true ; 否则返回 false ,则判断式为非真时,条件成立,执行 if 函数,故填:

!InSet(*s)

第二空是将不重复的元素加入至集合中,第18行中将数组元素赋值为 0 ,且每次判断后,对传入的数组地址进行自增操作,即进行遍历,因此每次复制后也需要对 num 进行自增操作,故填:

setdata[num++] = *s

第三空的目的是测试元素 c 是否与集合中某元素相同,且外层有一个 if 循环,故填:

c == setdata[i]

第四空根据题意可得,如果字符存在就返回 true ,故填:

return true

随机输入字符串后输出结果如下,符合题意:

图片[11] - C++ 应用题专项 - NCER - 岁有余生
输出结果

动物类

该工程中包含程序文件 main.cpp ,其中有类 Mammal (“哺乳动物”)、类 Elephant (“大象”)、类 Mouse (“老鼠”)的定义和主函数 main 的定义。请在横线处填写适当的代码并删除横线,以实现上述定义。此程序的正确输出结果应为:

ELEPHANT
MOUSE

注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include <iostream>
using namespace std;

enum category {EMPTY, ELEPHANT, MOUSE};
char* output[]={"EMPTY","ELEPHANT","MOUSE"};

class Mammal
{
public:
    Mammal(char* str)
    {
        //**********found**********        
        name = new ___________________
        strcpy(name,str);
    }
    virtual char* WhoAmI()=0;
    virtual ~Mammal() { delete[] name; }
    void Print() { cout<<WhoAmI()<<endl; }
private:
    char* name;
};

class Elephant : public Mammal
{
public:
    //**********found**********
    Elephant(char* str) : ______________ { }
    char* WhoAmI() { return output[ELEPHANT]; }
};

class Mouse : public Mammal
{
public:
    Mouse(char* str) : Mammal(str) { }
    //**********found**********
    char* WhoAmI() { ___________________ }
};

int main()
{
    //**********found**********
    Mammal *pm = new ________("Huanhuan");
    pm->Print();
    delete pm;

    pm = new Mouse("Micky");
    pm->Print();
    delete pm;

    return 0;
}

第一空考察的是对 strlen 函数的应用,根据题意可得,该空是给 name 分配一个空间,将 str 字符串赋值给 name 则可以推测出,分配的动态空间大小应为该数组的长度加 1 ,则需要用到 strlen 函数,故写为:

char[strlen(str) + 1]

第二空考察的是对构造函数的掌握。由题意得,此处应为派生类调用基类得构造函数完成初始化,故填:

 Mammal(str)

第三空考察的是函数的输出,由题意得输出的结果还需要一个 MOUSE ,根据28行可得应填:

return output[MOUSE]

第四空考察的是对派生类多态条件的掌握,由题意得,此处应输出28行的内容,应为基类指针指向子类对象,故填:

Elephant

输出结果如下,符合题意:

图片[12] - C++ 应用题专项 - NCER - 岁有余生
输出结果

反向链表

函数 void Insert(node*q) 使程序能完成如下功能:从键盘输入一行字符,调用该函数建立反序单链表,再输出整个链表,请在横线处填写适当的代码并删除横线,以实现上述定义,注意,只能在横线处填写适当的代码。不要改动程序中的其他内容,也不要删除横线上方的提示符。

#include <iostream>
using namespace std;
struct node
{
  char data;
  node *link;
} *head;    //链表首指针
void Insert(node *q)        //将节点插入链表首部
{
//********found********
  __________________________;
  head=q;
}
int main()
{
  char ch;
  node *p;
  head=NULL;
  cout<<"Please input the string"<<endl;
  while((ch=cin.get())!='\n')
  {
//********found********
    _______________________;               //用new为节点p动态分配存储空间
    p->data=ch;
//********found********
    _____________________;                 //插入该节点
  }
  p=head;
  while(p!=NULL)
  {
    cout<<p->data;
    p=p->link;
  }
  cout<<endl;
  return 0;
}

第一空考察的是对单向线性链表的了解,函数功能是将节点插入链表首部,将一个元素插入链表首部,只需要将其插在,该节点的指针域指向头结点后即可,故填:

q->link = head

第二空考察的是 new 关键字,用 new 为节点 p 动态分配存储空间,故填:

p = new node

第三空考察的是对函数的调用,即将 p 插入该节点,故填:

Insert(p)

随机输入字符串后输出结果如下,符合题意:

图片[13] - C++ 应用题专项 - NCER - 岁有余生
输出结果
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容