题1:
InputOutput
描述
设计一个保存你个人信息的类,包含姓名和年龄。并使用以下代码测试
int main()
{
string name;
int year;
cin >> name >> year;
PersonInfo info(name, year);
cout << "I am " << info.Name() << ", " << info.Age() << " years old.\n";
return 0;
}
#include<iostream>
#include<string>
using namespace std;
class PersonInfo
{
public:
PersonInfo(string m_name, int m_year){name=m_name;year=m_year;}
string Name(){return name;}
int Age(){return year;}
private:
string name;
int year;
};
题2:
Composite
描述
计算机包含CPU和硬盘。请设计Computer、CPU、Disk类。并满足以下测试
int main()
{
string cpuType, diskType;
double frequency, capacity;
cin >> cpuType >> frequency >> diskType >> capacity;
CPU cpu(cpuType, frequency);
Disk disk(diskType, capacity);
Computer computer(cpu, disk);
computer.Print();
return 0;
}
输入
cpu类型 cpu主频 disk类型 disk容量
#include<iostream>
#include<string>
using namespace std;
class CPU
{
public:
CPU() {} //有非默认的对象初始化函数,则需要写无参构造函数
CPU(string _type, double _frenquency) :cpuType(_type), frenquency(_frenquency) {}
string gettype(void) { return this->cpuType; }
double getfreq(void) { return this->frenquency; }
private:
string cpuType;
double frenquency;
};
class Disk
{
public:
Disk() {}
Disk(string _type, double _capacity) :diskType(_type), capacity(_capacity) {}
string gettype(void) { return this->diskType; }
double getcapacity(void) { return this->capacity; }
private:
string diskType;
double capacity;
};
class Computer
{
public:
Computer() {}
Computer(CPU _cpu, Disk _disk) :C_CPU(_cpu), C_Disk(_disk) {}
void Print()
{
cout << "The computer has a cpu and a disk." << endl;
cout << "CPU type: " << C_CPU.gettype() << ", CPU frequency: " << C_CPU.getfreq() << " GHz" << endl;
cout << "disk type: " << C_Disk.gettype() << ", disk capacity: " << C_Disk.getcapacity() << " T" << endl;
//此处直接用类的对象调用的函数,并直接在输出里使用的,原函数的作用是返回值(见上,对这两个函数的构造)
}
private:
CPU C_CPU;
Disk C_Disk;
};
题三:
静态数据成员
描述
定义一个学生类Student如下:
class Student
{
private:
int age; //年龄
string name; //姓名
public:
static int count; //静态成员,表示学生人数
Student(int a, string n);
Student();
~Student();
void Print();
};
主函数的定义及程序的运行结果如下,请完成类的定义及类中各函数的实现代码,补充成一个完整的程序。
int main()
{
cout<<"count="<<Student::count<<endl;
Student s1, *p=new Student(23,"ZhangHong");
s1.Print();
p->Print();
delete p;
s1.Print();
Student Stu[4];
cout<<"count="<<Student::count<<endl;
return 0;
}
#include<iostream>
#include<string>
using namespace std;
int Student::count=0;
Student::Student(int a, string n)
{
age=a;
name=n;
count=5;
};
Student::Student(){age=0;name="NoName";}
Student::~Student(){}
void Student::Print()
{
cout<<"Name="<<name<<", "<<"age="<<age<<endl;
}
题4:
Ellipse
描述
已有一个点类Point,使用x和y两个参数确定:
class Point
{
private:
double x, y;
public:
Point(double a=0, double b=0):x(a),y(b) {}
~Point(){}
double getX() const { return x;}
double getY() const { return y;}
void setX(double a) { x = a; }
void setY(double b) { y = b; }
};
假定椭圆中心固定于原点 (0,0),则唯一由半长轴 x 和半短轴 y 确定,故可使用一个点对象作为椭圆类成员。由点类组合方式生成一个椭圆类:
class Ellipse
{
public:
Point pAxis;
Ellipse(double x = 0, double y = 0):pAxis(x,y) { }//这里在椭圆类里使用了点类的对象
~Ellipse() { }
Ellipse(const Ellipse&);
Ellipse transposition(); // 转置(交换长短半轴)
double area(); // 面积
double eccentricity(); // 离心率
string position(const Point); // 位置关系
};
测试多组数据,输入椭圆分别在x轴、y轴的截距的绝对值(半轴长)和点的坐标,要求:输出椭圆面积、椭圆离心率、点与椭圆的位置关系。
(点在椭圆内、上、外<==>输出“inside”“at”“outside”)
主函数提供如下:
int main()
{
double a,b;
while(cin>>a>>b)
{
Ellipse d1(a,b),d2(d1),d3=d2.transposition();
cout<<d1.area()<<endl;
cout<<d2.eccentricity()<<endl;
cin>>a>>b;
Point p(a,b);
cout<<d3.position(p)<<endl;
}
return 0;
}
注意:const double PI = acos(-1.0);声明为全局变量
Ellipse::Ellipse(const Ellipse&t)
{
this->pAxis=t.pAxis;
}//第一遍做时在这出错
Ellipse Ellipse::transposition()
{
double tempt1,tempt2;
tempt1=this->pAxis.getY();
tempt2 = this->pAxis.getX();
this->pAxis.setY(tempt2);
this->pAxis.setX(tempt1);
return *this;
}// 转置(交换长短半轴)这一段代码着重关注,学会用this!
double Ellipse::area()
{
return (PI*(pAxis.getX())*(pAxis.getY()));
}// 面积
double Ellipse::eccentricity()
{
if(pAxis.getX()>pAxis.getY())
return (sqrt(pAxis.getX()*pAxis.getX()-pAxis.getY()*pAxis.getY())/pAxis.getX());
else return (sqrt(pAxis.getY()*pAxis.getY()-pAxis.getX()*pAxis.getX())/pAxis.getY());
}// 离心率(注意分类讨论!)
string Ellipse::position(const Point p)
{
if((pow(p.getX(),2)/pow(this->pAxis.getX(),2))+(pow(p.getY(),2)/pow(this->pAxis.getY(),2))==1)
return "at";
if((pow(p.getX(),2)/pow(this->pAxis.getX(),2))+(pow(p.getY(),2)/pow(this->pAxis.getY(),2))>1)
return "outside";
else return "inside";
}
题五:
AdvancedInheritance
描述
不同的动物既有共性也有个性。鸟类会飞,鱼会游泳。请设计类的层次结构进行表示,并通过以下测试
int main()
{
Animal *animal;
string type, color;
bool Osteichthyes, daytime;
cin >> type >> color >> Osteichthyes;
Fish fish(type, color, Osteichthyes);
fish.Print(); //输出方式一
animal = &fish;
animal->Print();//输出方式二
cin >> type >> color >> daytime;
Bird bird(type, color, daytime);
bird.Print();//输出方式一
animal = &bird;
animal->Print();//输出方式二
return 0;
}
输入
鱼类型 鱼的颜色 是否硬骨鸟类型 鸟的颜色 是否白天活动
输出
见样例,冒号和逗号后有一个空格
//!!!这道题的要点在于,如何让Fish和Bird两个类的对象,调用具有相同名字的Print函数时,能够区分开二者,这就需要使用到 **类的层次结构** 的知识
#include<iostream>
#include<string>
using namespace std;
class Animal
{
public:
string type, color;
virtual void Print(){} //类的层次结构
};
class Fish: public Animal
{
public:
Fish(const string m_type,const string m_color,bool m_Osteichthyes)
{
type=m_type;
color=m_color;
Osteichthyes=m_Osteichthyes;
}
virtual void Print() // 类的层次结构
{ cout<<"type: "<<type<<", color: "<<color<<", Osteichthyes: "<< Osteichthyes <<endl;}
private:
bool Osteichthyes;
};
class Bird: public Animal
{
public:
Bird(const string m_type,const string m_color,bool m_daytime)
{
type=m_type;
color=m_color;
daytime=m_daytime;
}
virtual void Print() //类的层次结构
{ cout<<"type: "<<type<<", color: "<<color<<", daytime: "<<daytime<<endl;}
private:
bool daytime;
};
题六(points!):
有理数类
描述
设计一个有理数类Rational,要求对运算符“+”“-”“*”“/”和“+=”“-=”“=”“/=”进行重载,完成有理数的加减乘除以及加减乘除复合赋值运算;并且重载“<<”和“>>”操作符完成有理数的输入和输出。最后,重载“==”和“!=”比较两个有理数是否相等。
类的定义如下:
class Rational
{
private:
int z; //分子
int m; //分母
public:
Rational(int a=0, int b=1); //构造有理数分数,分子默认为0,分母默认为1
void yuefen(); //约分函数对分数化简
friend Rational operator+(const Rational &r1, const Rational &r2);
friend Rational operator-(const Rational &r1, const Rational &r2);
friend Rational operator*(const Rational &r1, const Rational &r2);
friend Rational operator/(const Rational &r1, const Rational &r2);
Rational & operator+=(const Rational &r);
Rational & operator-=(const Rational &r);
Rational & operator*=(const Rational &r);
Rational & operator/=(const Rational &r);
friend bool operator==(const Rational &, const Rational &);//判断两个有理数是否相等
friend bool operator!=(const Rational &, const Rational &);//判断两个有理数是否不等
friend ostream & operator<<(ostream &, const Rational &);
friend istream & operator>>(istream &, Rational &);
};
使用以下的main函数体进行测试:
int main()
{
Rational r1, r2, r3;
while (cin >> r1 >> r2)
{
cout << "r1 = " << r1 << "\n" << "r2 = " << r2 << endl;
r3 = r1 + r2;
cout << "r1+r2 = " << r3 << endl;
r3 = r1 - r2;
cout << "r1-r2 = " << r3 << endl;
r3 = r1 * r2;
cout << "r1*r2 = " << r3 << endl;
r3 = r1 / r2;
cout << "r1/r2 = " << r3 << endl;
cout << (r1 == r2) << " " << (r1 != r2) << endl;
cout << (r1 += r2) << endl;
cout << (r1 -= r2) << endl;
cout << (r1 *= r2) << endl;
cout << (r1 /= r2) << endl;
}
return 0;
}
注意:
-
***Rational& yuefen();该函数原理是求得分子和分母的最大公约数gcd,然后将m和z除以gcd得到最简分数形式。求最大公约数的方法叫做辗转相除法,具体可上网查询。
-
观察输出,负号总是在分子前,若输入不符合该情形,需做相应处理。
-
分数总以化简形式输出,可在所有成员函数及运算符函数内恰当位置调用yuefen函数予以保证***
int gcd(int a, int b)
{
int temp;
temp = a = abs(a);
b = abs(b);
a = a < b ? b : a;
b = temp < b ? temp : b;
if(a%b!=0)
return gcd(a%b,b);
else
return b;
}
Rational::Rational(int a, int b)
{
z=a;
m=b;
}
Rational operator+(const Rational &r1, const Rational &r2)
{
Rational r;
r.z=r1.z*r2.m+r2.z*r1.m;
r.m=r1.m*r2.m;
r.yuefen();
return r;
}
Rational operator*(const Rational &r1, const Rational &r2)
{
Rational r;
r.z=r1.z*r2.z;
r.m=r1.m*r2.m;
r.yuefen();
return r;
}
Rational operator-(const Rational &r1, const Rational &r2)
{
Rational r;
r.z=r1.z*r2.m-r2.z*r1.m;
r.m=r1.m*r2.m;
r.yuefen();
return r;
}
Rational operator/(const Rational &r1, const Rational &r2)
{
Rational r;
r.z=r1.z*r2.m;
r.m=r1.m*r2.z;
r.yuefen(); //注意yuefen()函数的不同调用方式
return r;
}
Rational& Rational::operator+=(const Rational &r)
{
int a=this->z,b=this->m;
this->z=a*r.m+r.z*b;
this->m=b*r.m;
yuefen(); //注意yuefen()函数的不同调用方式
return *this;
}
Rational & Rational::operator/=(const Rational &r)
{
int a=this->z,b=this->m;
this->z=a*r.m;
this->m=b*r.z;
yuefen();
return *this;
}
Rational & Rational::operator-=(const Rational &r)
{
int a=this->z,b=this->m;
this->z=a*r.m-r.z*b;
this->m=b*r.m;
yuefen();
return *this;
}
Rational & Rational::operator*=(const Rational &r)
{
int a=this->z,b=this->m;
this->z=a*r.z;
this->m=b*r.m;
yuefen();
return *this;
}
bool operator!=(const Rational &r1, const Rational &r2)//判断两个有理数是否不等
{
int t;
int r1m=0,r1z=0,r2m,r2z;
t = gcd(r1.z, r1.m);
r1z= r1z / t;
r1m = r1m / t;
t = gcd(r2.z, r2.m);
r2z = r2.z / t;
r2m = r2.m / t;
if (r1m == r2m&&r1z == r2z)
return false;
else
return true;
}
bool operator==(const Rational &r1, const Rational &r2)//判断两个有理数是否相等
{
int t;
int r1m=0,r1z=0,r2m,r2z;
t = gcd(r1.z, r1.m);
r1z= r1z / t;
r1m = r1m / t;
t = gcd(r2.z, r2.m);
r2z = r2.z / t;
r2m = r2.m / t;
if (r1m == r2m&&r1z == r2z)
return true;
else
return false;
}
ostream & operator<<(ostream &os, const Rational &r)
{
os<<r.z<<"/"<<r.m;
return os;
}
istream & operator>>(istream &is, Rational &r)
{
is>>r.z>>r.m;
r.yuefen();
return is;
}
void Rational::yuefen()
{
int x=abs(z),y=abs(m),t; //abs(),求绝对值函数
t=gcd(x,y);
z/=t;m/=t;
if(m<0)
{
z=-z;
m=-m;
}//控制负号一直在前面
}
题七:
Line
描述
表示点和线是几何学的基础。请实现模板类的点(Point2)以及线段(Line2),并计算线段长度 Line2::Length();完成以上类,并通过以下测试
int main()
{
Point2<double> pt1(1.0, 1.0);
Point2<double> pt2(3.0, 4.0);
Line2<double> line(pt1, pt2);
cout << line.Length() << endl;
int x1,y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
Line2<int> nLine(Point2<int>(x1, y1), Point2<int>(x2, y2));
cout << nLine.Length()<< endl;
return 0;
}
#include<iostream>
#include<cmath>
using namespace std;
template<class type>
class Point2
{
public:
Point2(type a,type b)
{
x=a;
y=b;
}
type x;
type y;
};
template<class type>
class Line2
{
public:
Line2(Point2<type> m_p1,Point2<type> m_p2):p1(m_p1),p2(m_p2){}
type Length()
{
return (sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2)));
}
private:
Point2<type> p1,p2;
type l1,l2;
};
题八:
铁轨
描述
某城市有一个火车站,铁轨铺设如图所示。有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站,但由于末端封闭,驶入C的车厢必须按照相反的顺序驶出C。对于每个车厢,一旦从A移入C,就不能再回到A了;一旦从C移入B,就不能回到C了。换句话说,在任一时刻,只有两种选择:A->C和C->B。
请编程判断:按给定的出站顺序,火车能否出站。
#include<iostream>
#include <stack>
using namespace std;
const int maxn=1005;
int n,rail[maxn];
int main()
{
while(scanf("%d",&n)==1)
{
stack<int > s;
for(int i=1;i<=n;i++)
{
cin>>rail[i];
}
int flag,a,b;
a=b=flag=1;
while(b<=n)
{
if(a==rail[b])
{
a++;
b++;
}
else if(!s.empty()&&s.top()==rail[b])
{
s.pop();
b++;
}
else if(a<=n)
s.push(a++);
else
{
flag=0;
break;
}
}
printf("%s\n",flag?"Yes":"No");
}
return 0;
}