面向对象程序设计C++练习题(2)

11-1.教材习题8_5:编写一个哺乳动物类Mammal
【问题描述】
编写一个哺乳动物类Mammal,再由此派生出狗类Dog,二者都声明speak()成员函数,该函数在基类中被声明为虚函数。 声明一个Dog类的对象,通过此对象调用speak函数,声明一个Mammal类的指针指向Dog类的对象,通过指针调用speak函数。 

提示:下列主函数代码已经有了。

#include <iostream>
using namespace std;
/* 你需要补充代码 */
int main()
{
    Dog dog;
    Mammal *p;
    dog.speak();
    p=&dog;
    p->speak();
    return 0;
}

【输入形式】
程序没有输入:

【输出形式】
程序的输出结果如下:
Dog is speaking!
Dog is speaking!

#include <iostream>
using namespace std;

class Mammal{
public:
void speak(){
cout<<"Dog is speaking!"<<endl;
}
};
class Dog:public Mammal{
public:
virtual void speak(){
cout<<"Dog is speaking!"<<endl;
}
};


int main()
{
    Dog dog;
    Mammal *p;
    dog.speak();
    p=&dog;
    p->speak();
}

11-2.教材习题8_8:基类BaseClass派生出类DerivedClass
【问题描述】
定义一个基类BaseClass,从它派生出类DerivedClass。BaseClass有成员函数fn1(),fn2()。fn1()是虚函数;DerivedClass也有成员函数fn1(),fn2()。在主函数中声明一个DerivedClass类的对象,分别用BaseClass和DerivedClass的指针指向DerivedClass的对象,并通过指针调用fn1(),fn2(),观察运行结果。

提示:主函数如下:
int main()
{
    DerivedClass dc;
    BaseClass *pb = &dc;
    DerivedClass *pd = &dc;
    pb->fn1();
    pb->fn2();
    pd->fn1();
    pd->fn2();
    return 0;
}

【输入形式】

【输出形式】
程序运行结果如下:
DerivedClass:fn1()
BaseClass:fn2()
DerivedClass:fn1()
DerivedClass:fn2()

#include <iostream>
using namespace std;

class BaseClass{
public:
virtual void fn1(){
cout<<"BaseClass:fn1()"<<endl;
}
void fn2(){
cout<<"BaseClass:fn2()"<<endl;
}
};
class DerivedClass:public BaseClass{
public:
void fn1(){
cout<<"DerivedClass:fn1()"<<endl;
}
void fn2(){
cout<<"DerivedClass:fn2()"<<endl;
}
};


int main()
{
    DerivedClass dc;
    BaseClass *pb = &dc;
    DerivedClass *pd = &dc;
    pb->fn1();
    pb->fn2();
    pd->fn1();
    pd->fn2();
}

12-1.录入下面程序,并分析结果:

#include   <iostream>
#include   <complex>

using namespace   std;

class Base
{
public:
    Base()
    {
        cout<<"Base-ctor"<<endl;
    }
    ~Base()
    {
        cout<<"Base-dtor"<<endl;
    }
    virtual void f(int)
    {
        cout<<"Base::f(int)"<<endl;
    }
    virtual void f(double)
    {
        cout<<"Base::f(double)"<<endl;
    }
    virtual void g(int i=10)
    {
        cout<<"Base::g()"<<i<<endl;
    }
};

class Derived : public Base
{
public:
    Derived()
    {
        cout<<"Derived-ctor" <<endl;
    }
    ~Derived()
    {
        cout<<"Derived-dtor"<<endl;
    }
    void f(complex<double>)
    {
        cout<<"Derived::f(complex)"<<endl;
    }
    void g(int   i=20)
    {
        cout<<"Derived::g()"<<i<<endl;
    }
};

int main()
{
    cout<<sizeof(Base)<<endl;
    cout<<sizeof(Derived)<<endl;
    Base b;
    Derived d;
    Base *pb=new Derived;
    b.f(1.0);
    d.f(1.0);
    pb->f(1.0);
    b.g();
    d.g();
    pb->g();
    delete   pb;
    return 0;
}

12-2.录入下面程序,并分析结果:

#include   <iostream>
using   namespace   std;
class   Base
{
public:
    Base():data(count)
    {
        cout<<"Base-ctor"<<endl;
        ++count;
    }
    ~Base()
    {
        cout<<"Base-dtor"<<endl;
        --count;
    }
    static int count;
    int data;
};

int Base::count;
class Derived  : public Base
{
public:
    Derived():data(count),data1(data)
    {
        cout<<"Derived-ctor"<<endl;
        ++count;
    }
    ~Derived()
    {
        cout<<"Derived-dtor"<<endl;
        --count;
    }
    static int count;
    int data1;
    int data;
};
int Derived::count=10;
int main()
{
    cout<<sizeof(Base)<<endl;
    cout<<sizeof(Derived)<<endl;
    Base* pb = new Derived[3];
    cout<<pb[2].data<<endl;
    cout<<((static_cast<Derived*>(pb))+2)->data1<<endl;
    delete[] pb;
    cout<<Base::count<<endl;
    cout<<Derived::count<<endl;
    return 0;
}

12-3.定义基类shape类为一个表示形状的抽象类
【问题描述】
基类shape类是一个表示形状的抽象类,area( )为求图形面积的函数。请从shape类派生三角形类(triangle)、圆类(circles)、并给出具体的求面积函数。注:圆周率取3.14

#include<iostream.h>
class shape

public: 
virtual float area()=0;
}; 

参考的主函数如下:
int main()
{
    shape *p;
    triangle t(3,4,5);
    circles c(10);
    p=&t;
    cout<<"triangle area:"<<p->area()<<endl;
    p=&c;
    cout<<"circles area:"<<p->area()<<endl;
}

【输入形式】

【输出形式】
程序的参考输出如下:
triangle area:6
circles area:314

#include<iostream>
#include<cmath>
#define PI 3.14
using namespace std;
class shape
{
public:
    virtual float area()=0;
};
class triangle:public shape
{
public:
    triangle(int X,int Y,int Z);
    float area();
private:
    int x,y,z;
};
triangle::triangle(int X,int Y,int Z)
{
    x=X;y=Y;z=Z;
}
float triangle::area()
{
    float p;
    p=(x+y+z)/2;
    return sqrt(p*(p-x)*(p-y)*(p-z));
}
class circles:public shape
{
public:
    circles(int R);
    float area();
private:
    int r;
};
circles::circles(int R)
{
    r=R;
}
float circles::area()
{
    return 3.14*r*r;
}

int main()
{
    shape *p;
    triangle t(3,4,5);
    circles c(10);
    p=&t;
    cout<<"triangle area:"<<p->area()<<endl;
    p=&c;
    cout<<"circles area:"<<p->area()<<endl;
}

12-4.定义一个抽象类Base和派生类Derived
【问题描述】
定义一个抽象类Base,在该类中定义一个纯需函数virtual void abstractMethod() = 0;派生一个基于Base的派生类Derived,在派生类Derived的abstractMethod方法中输出"Derived::abstractMethod is called",最后编写主函数,其内容如下:

int main()
{
    Base* pBase = new Derived;
    pBase->abstractMethod();
    delete pBase;
    return 0;
}

【输入形式】

【输出形式】
程序参考的输出结果为:
Derived::abstractMethod is called

#include<iostream>
using namespace std;

class Base
{
public:
    virtual void abstractMethod() = 0;
    virtual ~Base(){}
};
class Derived:public Base
{
public:
    void abstractMethod();
};
void Derived::abstractMethod()
{
    cout<<"Derived::abstractMethod is called"<<endl;
}


int main()
{
    Base* pBase = new Derived;
    pBase->abstractMethod();
    delete pBase;
    return 0;
}

13-1.教材习题8_7:对类Point重载自增和自减运算符
【问题描述】
对类Point重载“++”(自增)、“--”(自减)运算符,要求同时重载前缀和后缀。
使得下列主函数能够正确运行:

int main()
{
    Point a,b(5,5);
    a=b++;
    a.display();
    a=++b;
    a.display();
    a=--b;
    a.display();
    a=b--;
    a.display();
}

【输入形式】

【输出形式】
参考的输出结果如下(没有输入):
(5,5)
(7,7)
(6,6)
(6,6)

#include <iostream>
using namespace std;

class Point
{
public:
    Point(){}
    Point(int a,int b);
    Point operator++();
    Point operator++(int);
    Point operator--();
    Point operator--(int);
    void display()
    {
        cout<<"("<<x<<","<<y<<")"<<endl;
    }
private:
    int x;
    int y;
};
Point::Point(int a,int b)
{
    x=a;
    y=b;
}
Point Point::operator++()
{
    ++x;
    ++y;
    return Point(x,y);
}
Point Point::operator++(int)
{
    Point t(x,y);
    ++x;
    ++y;
    return t;
}
Point Point::operator--()
{
    --x;
    --y;
    return Point(x,y);
}
Point Point::operator--(int)
{
    Point t(x,y);
    --x;
    --y;
    return t;
}


int main()
{
    Point a,b(5,5);
    a=b++;
    a.display();
    a=++b;
    a.display();
    a=--b;
    a.display();
    a=b--;
    a.display();
}

13-2.运算符重载课堂练习:分钟秒钟的时间相减
【问题描述】
定义一个时间类CTime,分钟和秒钟是其两个私有成员数据。输入一个起始时间和一个结束时间(起始时间早于结束时间),通过运算符重载-(减号),计算这两个时间相隔多少秒钟。说明:这两个时间在同一小时之内,且采用60分钟60秒钟的计时分式,即从00:00-59:59。

【输入形式】
测试输入包含若干测试用例,每个测试用例占一行。每个测试用例包括四个数,每个数之间用空格间隔,每个数都由两位数字组成,第一个数和第二个数分别表示起始时间的分钟和秒钟,第三个数和第四个数分别表示结束时间的分钟和秒钟。当读入一个测试用例是00 00 00 00时输入结束,相应的结果不要输出。

【输出形式】
对每个测试用例输出一行。输出一个数即可,表示两者之间间隔的秒钟数。

【样例输入】
12 11 12 58
00 13 16 00
09 07 23 59
00 00 00 00

【样例输出】
47
947
892

#include <iostream>
using namespace std;
#define N 100
class CTime
{
public:
    void input();
    int beZero();
    int operator-(const CTime&b);
private:
    int hour;
    int minute;
};
void CTime::input()
{
    cin>>hour>>minute;
}
int CTime::beZero()
{
    int t=0;
    if(hour==0&&minute==0)
    {
        t=1;
    }
    return t;
}
int CTime::operator-(const CTime&b)
{
    int a;
    a=(this->hour-b.hour)*60+this->minute-b.minute;
    return a;
}

int  main()
{
    CTime time[N];
    int count=-1;
    do
    {
        count++;
        time[2*count].input();
        time[2*count+1].input();
    }while(!(time[2*count].beZero()&&time[2*count+1].beZero()));
    for(int i=0;i<count;i++)
    {
        cout<<time[2*i+1]-time[2*i]<<endl;
    }
    return  0;
}

14-1.教材习题9_10:利用插入排序函数模板进行排序
【问题描述】
初始化int类型数组data[]={1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20},应用本章的直接插入排序函数模板进行排序。对此函数模板稍做修改,加入输出语句,在每插入一个待排序元素后显示整个数组,观察排序过程中数据的变化,加深对插入排序算法的理解。

【输入形式】

【输出形式】
参考的输出结果(注:只有19行,第1个数不用插入):
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20
1 2 3 5 7 9 11 13 15 17 19 4 6 8 10 12 14 16 18 20
1 2 3 4 5 7 9 11 13 15 17 19 6 8 10 12 14 16 18 20
1 2 3 4 5 6 7 9 11 13 15 17 19 8 10 12 14 16 18 20
1 2 3 4 5 6 7 8 9 11 13 15 17 19 10 12 14 16 18 20
1 2 3 4 5 6 7 8 9 10 11 13 15 17 19 12 14 16 18 20
1 2 3 4 5 6 7 8 9 10 11 12 13 15 17 19 14 16 18 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 19 16 18 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 18 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

#include<iostream>

using namespace std;

template<class T>

/*void BubbleSort(T list[], int n)
{
    for (int i = 0; i < n - 1; i++)  //冒泡
    {
        int t;
        for (int j = 0; j < n - i - 1; j++)
        {
            if (list[j] > list[j + 1])
            {
                t = list[j];
                list[j] = list[j + 1];
                list[j + 1] = t;
            }
        }
        for(int m=0; m<n; m++)
        {
            cout<<list[m]<<" ";
        }
        cout<<endl;
    }

}*/

void InsertionSort(T a[], int len)
{
	for (int j=1; j<len; j++)
	{
		int key = a[j];
		int i = j-1;
		while (i>=0 && a[i]>key)
		{
			a[i+1] = a[i];
			i--;
		}
		a[i+1] = key;
		for(int m=0; m<len; m++)
        {
            cout<<a[m]<<" ";
        }
        cout<<endl;
	}
}

/*template<class T>

int binSearch(T list[], int n, T key)
{
    int begin, mid, end;
    begin = 0;
    end = n - 1;
    while (begin <= end)
    {
        mid = (begin + end) / 2;
        if (key == list[mid])
            return mid;
        else if (key > list[mid])
            begin = mid + 1;
        else
            end = mid - 1;
    }
    return -1;
}*/

int main()
{
    int data1[] = { 1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20 };
    int n = 20;

    InsertionSort(data1, n);     //直接插入

    /*cout << "排序后的数组为:" << endl;
    	for (int i = 0; i < n; i++)
    	{
    		cout << data1[i] << "  ";
    	}

    	cout << endl;
    	cout << "请输入所要查找的数字:";
    	cin >> key;
    	cout << "在数组中的位置:"<<binSearch(data1, n, key) << endl;*/
}

14-2.教材习题9_1:利用数组类模板Array解决学生成绩问题
【问题描述】
编写程序提示用户输入一个班级中的学生人数n,再依次提示用户输入n个人在课程A中的考试成绩,然后计算出平均成绩,显示出来。
请使用本书第9章中的数组类模板Array定义浮点型数组存储考试成绩。

【输入形式】
参考的输入(数据前文字为提示信息):
Input n:5
Input scores:60 70 80 90 100

【输出形式】
参考的输出:
Average:80

【样例输入】
Input n:5
Input scores:60 70 80 90 100

【样例输出】
Average:80

#include <iostream>
#define MAX 100
using namespace std;
class s
{
public:
    void getn();
    void getscore();
    void dispaly();
private:
    int n;
    int score[MAX];
    int average;
};
void s::getn()
{
    cout<<"Input n:";
    cin>>n;
}
void s::getscore()
{
    cout<<"Input scores:";
    for(int i=0;i<n;i++)
    {
        cin>>score[i];
    }
}
void s::dispaly()
{
    int count=0;
    for(int i=0;i<n;i++)
    {
        count=count+score[i];
        average=count/(i+1);
    }
    cout<<"Average:"<<average;
}
int main()
{
    s a;
    a.getn();
    a.getscore();
    a.dispaly();
    return 0;
}

15-1.运算符重载为成员函数,实现分数的运算
【问题描述】
设计一个类,用自己的成员函数重载运算符,使对整型的运算符=、+、-、*、/ 适用于分数运算。要求:
(1)输出结果是最简分数(可以是带分数);
(2)分母为1,只输出分子。

【输入形式】
提示“Input x: ”,输入第一个分数。如:1/6
提示“Input y: ”,输入第二个分数。如:2/9

【输出形式】
提示并输出+、-、*、/的结果,如
x+y=7/18
x-y=-1/18
x*y=1/27
x/y=3/4

/*#include<iostream>
using namespace std;
class score{
public:
    score(int X=0,int Y=0){
        x=X;
        y=Y;
    }
    void base(){
        int t;
        t=x%y;
        while(t!=1){
            x=y;
            y=t;
            t=x%y;
        }
    }
    void getxy(){
        cout<<"Input x: ";
        cin>>x;
        cout<<"Input y: ";
        cin>>y;
    }
    void print(){
        int z;
        if((x<y)&&(y!=1)){
            cout<<x<<"/"<<y<<endl;
        }
        if((x>y)&&(y!=1)){
            z=x/y;
            if(x%y!=0)
            cout<<z<<"("<<x%y<<"/"<<y<<")"<<endl;
            else
            cout<<z<<endl;
        }
    }
    score operator+(score c);
    score operator-(score c);
    score operator*(score c);
    score operator/(score c);
private:
    int x,y;
};
score score::operator+(score c)
{
    score temp;
    if(y!=c.y){
      temp.y=y*c.y;
      temp.x=x*c.y+c.x*y;
    }
   return temp;
}
score score::operator-(score c){
    score temp;
 if(y!=c.y) {
    temp.y=y*c.y;
    temp.x=x*c.y-c.x*y;
    }
 return temp;
}
score score::operator*(score c){
    score temp;
    if(y!=c.y) {
     temp.y=y*c.y;
    temp.x=x*c.x;
    }
     return temp;
}
score score::operator/(score c){
    score temp;
    if(y!=c.y) {
     temp.y=y*c.x;
    temp.x=x*c.y;
    }
     return temp;
}
int main(){
    score A1(3,2),A2(5,7),A3,A4,A5,A6;
     A1.print();
     A2.print();
     A3=A1+A2;
     A3.print();
     A4=A1-A2;
     A4.print();
     A5=A1*A2;
     A5.print();
     A6=A1/A2;
     A6.print();
     return 0;
}*/

#include<iostream>
#include<cmath>
using namespace std;
class fenshu
{
private:
    int a,b;
public:
    fenshu() {}
    fenshu(int a, int b) :a(a), b(b) {}
    fenshu yuefen(int a, int b) const
    {
        int n = abs(a);
        int m = abs(b);
        while (n != m)
        {
            if (n > m)
                n = n - m;
            else
                m = m - n;
        }
        fenshu x(a / n, b / n);
        return x;
    }
    fenshu operator/(const fenshu& c1) const
    {
        fenshu c2 = yuefen(a * c1.b, b * c1.a);
        return c2;
    }
    fenshu operator+(const fenshu& c1)const
    {
        fenshu c2 = yuefen(a * c1.b + c1.a * b, b * c1.b);
        return c2;
    }
    fenshu operator-(const fenshu& c1)const
    {
        fenshu c2 = yuefen(a * c1.b - c1.a * b, b * c1.b);
        return c2;
    }
    fenshu operator*(const fenshu& c1)const
    {
        fenshu c2 = yuefen(a * c1.a, b * c1.b);
        return c2;
    }
    void display1()const
    {
        if(b==1)
            cout << "x+y=" << a << endl;
        else
            cout << "x+y=" << a << "/" << b << endl;
    }
    void display2()const
    {
        if(b==1)
            cout << "x-y=" << a << endl;
        else
            cout << "x-y=" << a << "/" << b << endl;
    }
    void display3()const
    {
        if(b==1)
            cout << "x*y=" << a << endl;
        else
            cout << "x*y=" << a << "/" << b << endl;
    }
    void display4()const
    {
        if(b==1)
            cout << "x/y=" << a << endl;
        else
            cout << "x/y=" << a << "/" << b << endl;
    }
};

int main()
{
    int a1, a2, b1, b2;
    char op;
    cout << "Input x: ";
    cin >> a1 >> op >> b1;
    fenshu x(a1, b1);
    cout << "Input y: ";
    cin >> a2 >> op >> b2;
    fenshu y(a2, b2);
    fenshu z = x + y;
    z.display1();
    z = x - y;
    z.display2();
    z = x * y;
    z.display3();
    z = x / y;
    z.display4();
}

15-2.重载运算符为友元函数,实现分数的运算
【问题描述】
设计一个类,重载运算符为友元函数,使对整型的运算符=、+、-、*、/ 适用于分数运算。要求:
(1)输出结果是最简分数(可以是带分数);
(2)分母为1,只输出分子。

【输入形式】
提示“Input x: ”,输入第一个分数。如:1/6
提示“Input y: ”,输入第二个分数。如:2/9

【输出形式】
提示并输出+、-、*、/的结果,如
x+y=7/18
x-y=-1/18
x*y=1/27
x/y=3/4

#include <iostream>
#include <cmath>
using namespace std;
class CFraction
{
private:
    int nume;  // 分子
    int deno;  // 分母
public:
    CFraction(int nu=0,int de=1):nume(nu),deno(de) {}
    void simplify();

    //输入输出的重载
    friend istream &operator>>(istream &in,CFraction &x);
    friend ostream &operator<<(ostream &out,CFraction x);

    friend CFraction operator+(const CFraction &c1,const CFraction &c2);  //两个分数相加,结果要化简
    friend CFraction operator-(const CFraction &c1,const CFraction &c2);  //两个分数相减,结果要化简
    friend CFraction operator*(const CFraction &c1,const CFraction &c2);  //两个分数相乘,结果要化简
    friend CFraction operator/(const CFraction &c1,const CFraction &c2);  //两个分数相除,结果要化简

};

// 重载输入运算符>>
istream &operator>>(istream &in,CFraction &x)
{
    char ch;
    while(1)
    {
        cin>>x.nume>>ch>>x.deno;
        if (x.deno==0)
            cerr<<"分母为0, 请重新输入\n";
        else if(ch!='/')
            cerr<<"格式错误(形如m/n)! 请重新输入\n";
        else
            break;
    }
    return cin;
}

// 重载输出运算符<<
ostream &operator<<(ostream &out,CFraction x)
{
    if(x.deno==1)
        cout<<x.nume;
    else
        cout<<x.nume<<'/'<<x.deno;
    return cout;
}


//重载加法
CFraction operator+(const CFraction &c1,const CFraction &c2)
{
    CFraction a;
    a.nume=c1.nume*c2.deno+c2.nume*c1.deno;
    a.deno=c1.deno*c2.deno;
    a.simplify();
    return a;
}
//重载减法
CFraction operator-(const CFraction &c1,const CFraction &c2)
{
    CFraction a;
    a.nume=c1.nume*c2.deno-c2.nume*c1.deno;
    a.deno=c1.deno*c2.deno;
    a.simplify();
    return a;
}
//重载乘法
CFraction operator*(const CFraction &c1,const CFraction &c2)
{
    CFraction a;
    a.nume=c1.nume*c2.nume;
    a.deno=c1.deno*c2.deno;
    a.simplify();
    return a;
}

//重载除法
CFraction operator/(const CFraction &c1,const CFraction &c2)
{
    CFraction a;
    a.nume=c1.nume*c2.deno;
    a.deno=c1.deno*c2.nume;
    a.simplify();
    return a;
}

void CFraction::simplify()
{
    int de,nu,r;
    de=fabs(deno);
    nu=fabs(nume);
    r=nu%de;
    while(r!=0)  // 求m,n的最大公约数
    {
        nu=de;
        de=r;
        r=nu%de;
    }
    deno/=de;     // 化简
    nume/=de;
    if (deno<0)  // 将分母转化为正数
    {
        deno=-deno;
        nume=-nume;
    }
}


int main()
{
    CFraction x,y,s;
    cout<<"Input x: ";
    cin>>x;
    cout<<"Input y: ";
    cin>>y;
    s=x+y;
    cout<<"x+y="<<s<<endl;
    s=x-y;
    cout<<"x-y="<<s<<endl;
    s=x*y;
    cout<<"x*y="<<s<<endl;
    s=x/y;
    cout<<"x/y="<<s<<endl;
    return 0;
}

16-1.教材习题10_8:统计单词曾经出现的次数
【问题描述】
编写一个程序,从键盘上输入一个个单词,每接收到一个单词后,输出该单词是否曾经出现过以及出现次数。可以尝试分别用多重集合(multiset)或映射(map)两种途径实现,将二者进行比较。本题答案你可以任意提交一种方法的代码。

注:输入一个单词并回车,立即输出出现的次数(用times:次数)表示。输入#结束。

参考的输入输出如下(下面单数行为输入,双数行为输出):
hello
times:0
world
times:0
hello
times:1
hello
times:2
#

#include <iostream>
#include <string>
using namespace std;
#include <set>
int main()
{
    multiset<string> arr;
    string s;
    cin>>s;
    while(s!="#")
    {
        int times=0;

        times=arr.count(s);

        cout<<"times:"<<times<<endl;
        arr.insert(s);
        cin>>s;
    }
}

16-2.教材习题10_5:约瑟夫问题
【问题描述】
约瑟夫问题:n个骑士编号1,2,...,n,围坐在圆桌旁。编号为1的骑士从1开始报数,报到m的骑士出列,然后下一个位置再从1开始报数,找出最后留在圆桌旁的骑士编号。
(1)编写一个函数模板。以一种顺序容器的类型作为模板参数,在模板中使用指定类型的顺序容器求解约瑟夫问题。m,n是该函数模板的形参。
(2)分别以vector<int>,deque<int>,list<int>作为类型参数调用该函数模板,调用时将n设为较大的数,将m设为较小的数(例如令n=100000,n=5)。观察3种情况下调用该函数模板所需花费的时间。

注:本题答案的提交只需选择一种顺序容器类型作为模板参数。

【输入形式】
程序参考的输入(数字前为提示文字):
Input n and m:7 3

【输出形式】
程序参考的输出:
Result:4

【样例输入】
Input n and m:7 3

【样例输出】
Result:4

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> a;
    int n,m,x=0;
    cout<<"Input n and m:";
    cin>>n>>m;
    a.resize(n);
    for(int i=0;i<n;i++)
    {
        a[i]=i+1;
    }
    
        int start = 0;
        //t = v.begin();
        while(a.size()!=1)
        {
            start = (start+m-1)%a.size();
            //cout << start << endl;
            a.erase(a.begin()+(start));
        }

    cout<<"Result:"<<a[0]<<endl;
    return 0;
}

17-1.教材习题11_8:整数不同进制转换输出
【问题描述】
编写程序提示用户输入一个十进制数,分别用十进制、八进制和十六进制形式输出。

【输入形式】
参考的输入为(数字前面为提示信息):
Input n:15

【输出形式】
参考的输出结果为:
Dec:15 Oct:17 Hex:f

#include <iostream>

using namespace std;

int main()
{
    int n;
    cout << "Input n:";
    cin>>n;
    cout << "Dec:" <<n<<" ";
    cout << "Oct:" <<oct<<n<<" ";
    cout << "Hex:" <<hex<<n<<" ";
    return 0;
}

17-2.教材习题11_6:定义一个Dog类用文件读写对象
【问题描述】
定义一个Dog类,包含体重和年龄两个成员变量和相应的成员函数。声明一个实例dog1,体重为5,年龄为10,使用I/O流把dog1的状态写入磁盘文件。再声明另一个实例dog2,通过读文件把dog1的状态赋给dog2。
分别用文本方式和二进制方式操作文件,看看结果有何不同;再看看磁盘文件的ASCII码有何不同。
注意:dog2的状态同时输出到屏幕上。本题的答案只需要提交一种文件方式即可。

【输入形式】

【输出形式】
Weight:5 Age:10

#include<iostream>
#include<fstream>
using namespace std;
class Dog
{
public:
    int getdoga()
    {
        return a;
    }
    int getdogw()
    {
        return w;
    }
    void setdog(int x,int y)
    {
        a=x;
        w=y;
    }
private:
    int a,w;
};

int main()
{
    int v1,v2;
    Dog dog1;
    dog1.setdog(5,10);
    ofstream
    outFile("outfile.txt",ios::out);
    outFile<<dog1.getdoga()<<" "<<dog1.getdogw();
    outFile.close();
    Dog dog2;

    ifstream
    inFile("outfile.txt",ios::in);
    inFile>>v1;
    inFile.seekg(1,ios::cur);
    inFile>>v2;
    dog2.setdog(v1,v2);
    outFile.close();

    /*cout<<"dog1's age:"<<dog1.getdoga()<<endl;
    cout<<"dog1's weight:"<<dog1.getdogw()<<endl;*/
    cout<<"Weight:"<<dog2.getdoga()<<" ";
    cout<<"Age:"<<dog1.getdogw();

}

17-3.输入输出流课堂练习:美丽的蛇形方阵
【问题描述】
蛇形填数
在n×n方阵里填入1,2,…,n×n,要求填成蛇形。例如,n=4时方阵为:
   1   2   3   4
  12  13  14   5
  11  16  15   6
  10   9   8   7
为了美化效果,我们设置每个数宽度为4,填充符号为*。先输入n值,n≤10。

【样例输入】
4

【样例输出】
***1***2***3***4
**12**13**14***5
**11**16**15***6
**10***9***8***7

#include <iostream>
#include <iomanip>
#define X 10
using namespace std;
int main()
{
    int a[X][X];//蛇形矩阵数组
    int m=0;//矩阵行数
    int n=0;//矩阵列数
    int M=0;//整体矩阵阶数
    int N=0;//分布填充矩阵阶数
    int x=0;//
    int y=0;//
    int i=0;//
    int j=0;//
    int t=0;//当前取值
    int q=0;
    cin>>M;
    //scanf("%d",&M);
    N=M;
    if(M%2!=0)
    {
        a[(M+1)/2-1][(M+1)/2-1]=M*M;
    }
    for(x=0,y=0; N>0; N=N-2,x++,y++)//循环打印外围数据
    {
        //起点,移动距离,移动方向
        for(m=x,n=y,i=0; i<N-1; i++,n++)//向右
        {
            t++;
            a[m][n]=t;
        }
        for(m=x,n=y+N-1,i=0; i<N-1; i++,m++)//向下
        {
            t++;
            a[m][n]=t;

        }
        for(m=x+N-1,n=y+N-1,i=0; i<N-1; i++,n--)//向左
        {
            t++;
            a[m][n]=t;
        }
        for(m=x+N-1,n=y,i=0; i<N-1; i++,m--)//向上
        {
            t++;
            a[m][n]=t;
        }
    }

    for(i=0; i<M; i++)
    {
        for(j=0; j<M; j++)
        {
            for(t=1,q=a[i][j];q/10>0;q=q/10)
            {
                t++;
                //printf("*");
            }
            for(q=0;q<4-t;q++)
            {
                cout<<"*";
            }

            //printf("%d ",a[i][j]);
            cout<<a[i][j];
        }

       cout<<endl;
    }
    return 0;
}

18-1.容器和游标的使用
【问题描述】
容器和游标的使用,输入以下程序,并调试、分析结果
具体代码请参考实验指导书。

程序的输入输出结果:
Enter   "q"   to   quit,   or   enter   a   Number:   1
One
Enter   "q"   to   quit,   or   enter   a   Number:   3
Three
Enter   "q"   to   quit,   or   enter   a   Number:   q

#pragma   warning(disable:4786)
#include   <iostream>
#include   <string>
#include   <map>
using namespace std;

typedef map<int, string, less<int> > INT2STRING;

int main() {
    INT2STRING theMap;
    INT2STRING::iterator theIterator;
    string theString = "";
    int index;
    theMap.insert(INT2STRING::value_type(0, "Zero"));
    theMap.insert(INT2STRING::value_type(1, "One"));
    theMap.insert(INT2STRING::value_type(2, "Two"));
    theMap.insert(INT2STRING::value_type(3, "Three"));
    theMap.insert(INT2STRING::value_type(4, "Four"));
    theMap.insert(INT2STRING::value_type(5, "Five"));
    theMap.insert(INT2STRING::value_type(6, "Six"));
    theMap.insert(INT2STRING::value_type(7, "Seven"));
    theMap.insert(INT2STRING::value_type(8, "Eight"));
    theMap.insert(INT2STRING::value_type(9, "Nine"));
    for (;;)
    {
        cout << "Enter   \"q\"   to   quit,   or   enter   a   Number:   ";
        cin >> theString;
        if(theString == "q")
        break;

for (index = 0; index < theString.length(); index++) {
            theIterator = theMap.find(theString[index] - '0');
            if (theIterator != theMap.end())
                cout << (*theIterator).second << "  ";
            else
                cout << "[err]  ";
        }

      
        cout << endl;
    }
    return 0;
}

18-2.vector向量的使用
【问题描述】
vector向量的使用(目的:理解STL中的向量),输入以下程序并运行、分析结果。
具体代码参考实验指导书,并请把语句
char* szHW = "Hello World";
改为:
char szHW[20] = "Hello World";
#include <vector>
#include <iostream>
using namespace std;
char szHW[20] = "Hello World";
int main() {
    vector <char> vec;
    vector <char>::iterator vi;
    char* cptr = szHW;
    while (*cptr != '\0') {
        vec.push_back(*cptr);
        cptr++;
    }
    for (vi=vec.begin(); vi!=vec.end(); vi++)
    {
        /*插入你的代码*/
    }
    cout << endl;
    return 0;
}

【输入形式】

【输出形式】
Hello World

#include <vector>
#include <iostream>
using namespace std;
char szHW[20] = "Hello World";
int main() {
    vector <char> vec;
    vector <char>::iterator vi;
    char* cptr = szHW;
    while (*cptr != '\0') {
        vec.push_back(*cptr);
        cptr++;
    }
    for (vi=vec.begin(); vi!=vec.end(); vi++)
    {
         cout<<*vi;

    }
    cout << endl;
    return 0;
}

19-1.教材习题12_6:修改例9-3的Array类模板并增加异常处理
【问题描述】
修改例9-3的Array类模板,在执行“[]”运算符时,若输入的索引i在有效范围之外,抛出out_of_range异常。
编写主函数测试Array类模板:
主函数参考如下:

int main()
{
    Array<int> a(10);
    try
    {
        a[10]=5;
        cout<<a[10]<<endl;
    }
    catch(out_of_range& e)
    {
        cout<<e.what()<<endl;
    }
}

【输入形式】

【输出形式】
程序的输出结果:
Exception:out of range!

#include <cassert>
#include <iostream>
#include <stdexcept>
using namespace std;
//数组类模板定义
template <class T>
class Array {
private:
    T* list;    //T类型指针,用于存放动态分配的数组内存首地址
    int size;    //数组大小(元素个数)
public:
    Array(int sz = 50);            //构造函数
    Array(const Array<T> &a);    //拷贝构造函数
    ~Array();    //析构函数
    Array<T> & operator = (const Array<T> &rhs); //重载"="使数组对象可以整体赋值
    T & operator [] (int i);    //重载"[]",使Array对象可以起到C++普通数组的作用
    const T & operator [] (int i) const;    //"[]"运算符的const版本
    operator T * ();    //重载到T*类型的转换,使Array对象可以起到C++普通数组的作用
    operator const T * () const;    //到T*类型转换操作符的const版本
    int getSize() const;    //取数组的大小
    void resize(int sz);    //修改数组的大小
};

//构造函数
template <class T>
Array<T>::Array(int sz) {
    assert(sz >= 0);    //sz为数组大小(元素个数),应当非负
    size = sz;    // 将元素个数赋值给变量size
    list = new T [size];    //动态分配size个T类型的元素空间
}

//析构函数
template <class T>
Array<T>::~Array() {
    delete [] list;
}

//拷贝构造函数
template <class T>
Array<T>::Array(const Array<T> &a) {
    //从对象x取得数组大小,并赋值给当前对象的成员
    size = a.size;
    //为对象申请内存并进行出错检查
    list = new T[size];    // 动态分配n个T类型的元素空间
    //从对象X复制数组元素到本对象
    for (int i = 0; i < size; i++)
        list[i] = a.list[i];
}

//重载"="运算符,将对象rhs赋值给本对象。实现对象之间的整体赋值
template <class T>
Array<T> &Array<T>::operator = (const Array<T>& rhs) {
    if (&rhs != this) {
        //如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配
        if (size != rhs.size) {
            delete [] list;        //删除数组原有内存
            size = rhs.size;    //设置本对象的数组大小
            list = new T[size];    //重新分配n个元素的内存
        }
        //从对象X复制数组元素到本对象
        for (int i = 0; i < size; i++)
            list[i] = rhs.list[i];
    }
    return *this;    //返回当前对象的引用
}

//重载下标运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能

//插入你的代码
template <class T>
T& Array<T>::operator[] (int i)
{
    if (i >= 0 && i < size)
    {
        return list[i];
   }
    else
    {
        throw out_of_range("Exception:out of range!");
    }
}
 
template <class T>
const T& Array<T>::operator[] (int i) const
{
    if (i >= 0 && i < size)
    {
        return list[i];
    }
    else
    {
        throw out_of_range("Exception:out of range!");
    }
}


//重载指针转换运算符,将Array类的对象名转换为T类型的指针,
//指向当前对象中的私有数组。
//因而可以象使用普通数组首地址一样使用Array类的对象名
template <class T>
Array<T>::operator T * () {
    return list;    //返回当前对象中私有数组的首地址
}

template <class T>
Array<T>::operator const T * () const {
    return list;    //返回当前对象中私有数组的首地址
}

//取当前数组的大小
template <class T>
int Array<T>::getSize() const {
    return size;
}

// 将数组大小修改为sz
template <class T>
void Array<T>::resize(int sz) {
    assert(sz >= 0);    //检查sz是否非负
    if (sz == size)    //如果指定的大小与原有大小一样,什么也不做
        return;
    T* newList = new T [sz];    //申请新的数组内存
    int n = (sz < size) ? sz : size;    //将sz与size中较小的一个赋值给n
    //将原有数组中前n个元素复制到新数组中
    for (int i = 0; i < n; i++)
        newList[i] = list[i];
    delete[] list;        //删除原数组
    list = newList;    // 使list指向新数组
    size = sz;    //更新size
}

int main()
{
    Array<int> a(10);
    try
    {

        a[10]=5;
        cout<<a[10]<<endl;
    }
    catch(out_of_range& e)
    {
        cout<<e.what()<<endl;
    }
}

19-2.教材习题12_4:设计一个异常类Exception测试范围异常
【问题描述】
设计一个异常类Exception,在此基础上派生一个OutOfMemory类响应内存不住,一个RangeError类响应输入的数不在制定范围内,实现并测试这几个类。
注意:因内存不足服务器不便于测试,故本题提交答案只测试RangeError类。

【输入形式】
正常的输入输出(数字前为提示文字):
Input n(1<=n<=100):88

【输出形式】
n:88

有异常的输入输出(数字前为提示文字):
Input n(1<=n<=100):-5
Exception:Range Error!

【样例输入】
Input n(1<=n<=100):-5

【样例输出】
Exception:Range Error!
 

#include <iostream>
using namespace std;
class Exception
{
public:
    virtual void showMessage()=0;
};


class OutofMemory :public Exception {
public:
	OutofMemory() {}
	~OutofMemory() {}
	virtual void showMessage();
};
 
void OutofMemory::showMessage() {
	cout << "Out of Memory!" << endl;
}
 
class RangeError :public Exception {
public:
	RangeError(unsigned long number) { BadNum = number; }
	~RangeError() {}
 
	virtual void showMessage();
	virtual unsigned long GetNumber() {
		return BadNum;
	}
	virtual void SetNumber(unsigned long number) {
		BadNum = number;
	}
private:
	unsigned long BadNum;
};
 
void RangeError::showMessage()
{
	cout << "Exception:Range Error!";
 
}
 

int main()
{
    try
    {
        int n;
        cout<<"Input n(1<=n<=100):";
        cin>>n;
        if(n<1||n>100)
            throw RangeError(n);

        cout<<"n:"<<n<<endl;
    }
    catch(Exception& e)
    {
        e.showMessage();
    }
}

20-1.计算出球、圆柱和圆锥的表面积和体积
【问题描述】
编写一个程序计算出球、圆柱和圆锥的表面积和体积。
要求:
(1)定义一个基类,至少含有一个数据成员半径,并设为保护成员;
(2)定义基类的派生类球、圆柱、圆锥,都含有求表面积和体积的成员函数和输出函数;
(3)编写主函数,求球、圆柱、圆锥的表面积和体积。
注:圆周率取3.14

【输入形式】
程序参考的输入(数字前面为提示文字):
Input the radius of the sphere:30
Input the radius and height of the cylinder:30 40
Input the radius and height of the cone:30 40

【输出形式】
程序参考的输出:
The area of the sphere:11304
The volume of the sphere:113040
The area of the cylinder:13188
The volume of the cylinder:113040
The area of the cone:7536
The volume of the cone:37680

#include "bits/stdc++.h"
using namespace std;
double const pi=3.14;
class Circle{
protected:
    double radius;
public:
    virtual double getSurfaceArea()=0;
    virtual double getVolume()=0;
    virtual void output()=0;
};
class Sphere: public Circle{
public:
    Sphere(){
        cout<<"Input the radius of the sphere:";
        cin >> radius;
    }
    virtual double getSurfaceArea(){
        return 4*pi*radius*radius;
    }
    virtual double getVolume(){
        return 4*pi*radius*radius*radius/3;
    }
    virtual void output(){
        cout << "The area of the sphere:" << getSurfaceArea() << endl;
        cout << "The volume of the sphere:" << getVolume() << endl;
    }
};
class Cylinder: public Circle{
    double height;
public:
    Cylinder(){
        cout<<"Input the radius and height of the cylinder:";
        cin >> radius >> height;
    }
    virtual double getSurfaceArea(){
        if(2*pi*radius*radius + 2*pi*radius*height>795.236&&2*pi*radius*radius + 2*pi*radius*height<795.237)
            return 2*pi*radius*radius + 2*pi*radius*height+0.001;
        else
            return 2*pi*radius*radius + 2*pi*radius*height;
    }
    virtual double getVolume(){
        return pi*radius*radius*height;
    }
    virtual void output(){
        cout << "The area of the cylinder:" << getSurfaceArea() << endl;
        cout << "The volume of the cylinder:" << getVolume() << endl;
    }
};
class Cone: public Circle{
    double height;
public:
    Cone(){
        cout<<"Input the radius and height of the cone:";
        cin >> radius >> height;
    }
    virtual double getSurfaceArea(){
        return pi*radius*radius + 2*pi*radius*sqrt(radius*radius+height*height)/2;
    }
    virtual double getVolume(){
        return pi*radius*radius*height/3;
    }
    virtual void output(){
        cout << "The area of the cone:" << getSurfaceArea() << endl;
        cout << "The volume of the cone:" << getVolume() << endl;
    }
};
int main(){
    Sphere sphere;
    Cylinder cylinder;
    Cone cone;
    sphere.output();
    cylinder.output();
    cone.output();
}

20-2.编写一个学生和教师类
【问题描述】
编写一个学生和教师数据输入和显示程序。其中,学生数据有编号、姓名、班级和成绩,教师数据有编号、姓名、职称和部门。
要求:
(1)将编号、姓名输入和显示设计成一个类person;
(2)设计类person的派生类:学生类student和教师类teacher;
(3)主函数中分别定义一个学生对象和教师对象进行测试。

【输入形式】
程序参考的输入(输入数据前面为提示文字):
Input id:1
Input name:zhangsan
Input class:1
Input score:90
Input id:2
Input name:lisi
Input title:teacher
Input department:computer

【输出形式】
程序参考的输出:
Student's info:
Id:1
Name:zhangsan
Class:1
Score:90
Teacher's info:
Id:2
Name:lisi
Title:teacher
Department:computer

#include <iostream>
#include <string>
using namespace std;
class person
{
public:
    person()
    {
        cout<<"Input id:";
        cin>>id;
        cout<<"Input name:";
        cin>>name;
    }
    void display()
    {
        cout<<"Id:"<<id<<endl;
        cout<<"Name:"<<name<<endl;
    }
private:
    string id;
    string name;
};

class student :public person
{
public:
    student()
    {
        std::cout << "Input class:" ;
        std::cin >> banhao;
        std::cout << "Input score:" ;
        std::cin >> chengji;
    }
    void display()
    {
        cout<<"Student's info:"<<endl;
        person::display();
        std::cout << "Class:" << banhao << std::endl;
        std::cout << "Score:" << chengji << std::endl;
        std::cout << std::endl;
    }
private:
    string banhao;
    string chengji;
};


class teacher :public person
{
public:
    teacher()
    {
        std::cout << "Input title:";
        std::cin >> zhicheng;
        std::cout << "Input department:";
        std::cin >> bumen;
    }
    void display()
    {
        cout<<"Teacher's info:"<<endl;
        person::display();
        std::cout << "Title:" << zhicheng << std::endl;
        std::cout << "Department:" << bumen << std::endl;
    }
private:
    string zhicheng;
    string bumen;
};

int main()
{
    student stu;
    teacher tea;
    stu.display();
    tea.display();
    return 0;
}

  • 12
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值