课后练习5、运算符重载(编程)

7-1 复数的比较

题目描述:建立一个复数类,实数和虚数是其私有数据成员。建立一个>(大于号)的运算符重载,比较两个复数间模的大小。

输入格式:测试输入包含若干测试用例,每个测试用例占一行。每个测试用例包括四个数字,前两个数字分别表示第一个复数的实部和虚部,第三个和第四个数字分别表示第二个复数的实部和虚部。每个数字之间用空格间隔。当读入一个测试用例是0 0 0 0时输入结束,相应的结果不要输出。

输出格式:对每个测试用例输出一行。当第一个复数的模大于第二个复数的模时,输出 true ,当第一个复数的模小于或等于第二个复数的模时,输出false

输入样例:

   3 5 4 0

   0 3 4 1

   0 0 0 0

输出样例:

   true

   false

#include <iostream>
using namespace std;

class Complex
{
private:
    double real,imag;
public:
    Complex(){}
    void set(double r,double i)
    {
        real = r;
        imag = i;
    }
    friend bool operator>(Complex c1,Complex c2);
};

bool operator>(Complex c1,Complex c2)
{
    return (c1.real * c1.real + c1.imag * c1.imag) > (c2.real * c2.real + c2.imag * c2.imag);
}

int main()
{
    double r1,i1,r2,i2;
    Complex c1, c2;
    cin >>r1>>i1>>r2>>i2;
    while (!(r1 == 0 && r2 == 0 && i1 == 0 && i2 == 0))
    {
        c1.set(r1,i1),c2.set(r2,i2);
        if(c1 > c2)
            cout<<"true"<<endl;
        else
            cout<<"false"<<endl;
        cin >>r1>>i1>>r2>>i2;
    }
}

7-2 运算符重载

请定义一个分数类,拥有两个整数的私有数据成员,分别表示分子和分母(分母永远为正数,符号通过分子表示)。
重载运算符加号"+",实现两个分数的相加,所得结果必须是最简分数。

输入:

第一行的两个数 分别表示 第一个分数的分子和分母(分母不为0)。 第二行的两个数 分别表示 第二个分数的分子和分母。

输出:

第一个数表示分子,第二个数表示分母(若分数代表的是整数,则不输出分母)。

输入样例:

1  5
2  5

输出样例:

3 5

 

#include <iostream>
using namespace std;

class fenshu
{
private:
    int x,y;
public:
    fenshu(){};
    void set(int a,int b)
    {
        x = a;
        y = b;
    }
    void print()
    {
        cout<<x;
        if(y != 1)
            cout<<" "<<y;
    }
    friend fenshu operator+(fenshu &s1,fenshu &s2);
};

fenshu operator+(fenshu &s1,fenshu &s2)
{
    fenshu s;
    s.y = s1.y * s2.y;
    s.x = s1.x * s2.y + s2.x * s1.y;
    for(int i = 2;i <= (s.x>s.y?s.x:s.y);i++)
    {
        if(s.x % i == 0 && s.y % i == 0)
        {
            s.x /= i;
            s.y /= i;
            i = 2;
        }
    }
    return s;
}
int main()
{
    fenshu s1,s2,s;
    int r1,i1,r2,i2;
    cin>>r1>>i1>>r2>>i2;
    s1.set(r1,i1);
    s2.set(r2,i2);
    s = s1 + s2;
    s.print();
    return 0;
}

 

7-3 复数相加

题目:一个复数类,运算符重载 + ,实现复数和复数的相加。输入一组复数,每行一个复数,直到输入0结束。 输出这组复数的结果。

提示: 复数的输入和输出符合数学书写规范

输入示例

3+2i

2+3i

0

输出示例

5+5i

#include <bits/stdc++.h>
using namespace std;

class Complex
{
	public:
		double r, i;
		Complex(double real = 0.0, double imag = 0.0): r(real), i(imag) {}
		Complex operator +(const Complex &a)
		{
			r = r + a.r;
			i = i + a.i;
			return  *this;
		}
		void display()
		{
			if (i > 0)
			{
				if (i == 1)
				{
					if (r == 0)
						cout << "i" << endl;
					else
						cout << r << "+" << "i" << endl;
				}
				else
				{
					if (r == 0)
						cout << i << "i" << endl;
					else
						cout << r << "+" << i << "i" << endl;
				}
			}
			else if (i < 0)
			{
				if (i == -1)
				{
					if (r != 0)
						cout << r;
					cout << "-i" << endl;
				}
				else
				{
					if (r == 0)
						cout << i << "i" << endl;
					else
						cout << r << i << "i" << endl;
				}
			}
			else
				cout << r << endl;
		}
};



int main()
{
	Complex a,b(0,0);
	string str;
    int v1, v2;
	while(1)
	{
		v1 = 0,v2 = 0;
        cin >> str;
        if(str == "0")
            break;
		if (str[str.length() - 1] != 'i')
		{
			//只有实部
			v2 = 0;
			if (str[0] == '-')
				v1 = -(atoi(str.substr(1).c_str()));
			else
				v1 = atoi(str.substr(0).c_str());
		}
		else
		{
			//有虚部
			int flagz = 0, flagf = -1;
			for (unsigned int j = 0; j < str.length(); j++)
			{
				if (str[j] == '+')
					flagz = j;
				if (str[j] == '-')
					flagf = j;
			}
			if (flagz == 0 && flagf == -1)
			{
				//没+也没-,只有正虚部
				v1 = 0;
				if (str == "i")
					v2 = 1;
				else
					v2 = atoi(str.substr(0, str.length() - 1).c_str());
			}
			else if (flagz == 0 && flagf == 0)
			{
				//没+且-在首位,只有负虚部
				v1 = 0;
				if (str == "-i")
					v2 = -1;
				else
					v2 = -(atoi(str.substr(1, str.length() - 2).c_str()));
			}
			else
			{
				if (flagz)
				{
					//有+,+前的是实部,虚部为正
					if (str[0] == '-')
						v1 = -atoi(str.substr(1, flagz - 1).c_str());
					else
						v1 = atoi(str.substr(0, flagz).c_str());
					if (str[flagz + 1] == 'i')
						v2 = 1;
					else
						v2 = atoi(str.substr(flagz + 1, str.length() - 2 - flagz).c_str());
				}
				else if (flagf > 0)
				{
					//出现-且不在首位,-前是实部,虚部为负
					if (str[0] == '-')
						v1 = -atoi(str.substr(1, flagf - 1).c_str());
					else
						v1 = atoi(str.substr(0, flagf).c_str());
					if (str[flagf + 1] == 'i')
						v2 = -1;
					else
						v2 = -atoi(str.substr(flagf + 1, str.length() - flagf - 2).c_str());
				}
			}
		}
		a = Complex(v1, v2);
        b = b+a;
	}
	b.display();
	return 0;
}

7-4 时间换算

定义一个时间类time,内有数据成员hour,minute,second,另有成员函数:构造函数用于初始化数据成员,输出函数,运算符重载+(加号),。编写主函数:创建时间对象,再输入秒数 n,通过运算符重载+(减号),计算该时间再过 n 秒后的时间值,时间的表示形式为时:分:秒,超过 24 时从 0 时重新开始计时。

  测试输入包含若干测试用例,每个测试用例占一行。当读入0 0 0 0时输入结束,相应的结果不要输出。

   
   输入输出示例:括号内为说明

   0 0 1 59 (时间为0:0:1,秒数n=59)

   11 59 40 30 (时间为11:59:40,秒数n=30)

   23 59 40 3011 (时间为23:59:40,秒数n=3011)

   0 0 0 0

   输出:

  time:0:1:0↙(0:0:01加上59秒的新时间)   

  time:12:0:10↙(11:59:40加上30秒的新时间)

  time:0:49:51↙(23:59:40加上3011秒的新时间)
#include<iostream>
using namespace std;
class Clock
{
private:
    int hours,minutes,seconds;
public:
    Clock(int a=0,int b=0,int c=0):hours(a),minutes(b),seconds(c){};
    void set(int a,int b,int c)
    {
        hours = a;
        minutes = b;
        seconds = c;
    }
    friend Clock operator+(Clock &a,int k);
    void print()
    {
        cout<<"time:"<<hours<<":"<<minutes<<":"<<seconds<<endl;
    }
};

Clock operator+(Clock &a,int k)
{
    Clock c;
    c.hours = a.hours,c.minutes = a.minutes,c.seconds = a.seconds+k;
    int cnt;
    if(c.seconds+k > 59 || c.seconds+k < 0)
    {
        cnt = (a.seconds + k) / 60;
        c.seconds = (a.seconds + k) % 60;
        c.minutes = a.minutes + cnt;
        if(c.seconds < 0)
        {
            c.seconds += 60;
            c.minutes--;
        }
        if(c.minutes > 59 || c.minutes < 0)
        {
            cnt = (c.minutes)/60;
            c.minutes %= 60;
            c.hours += cnt;
            if(c.minutes < 0)
            {
                c.minutes += 60;
                c.hours--;
            }
            if(c.hours > 23 || c.hours < 0)
            {
                c.hours = c.hours % 24;
                if(c.hours < 0)
                {
                    c.hours += 24;
                }
            }
        }
    }
    return c;
}

int main()
{
    Clock c;
    int h,m,s,k;
    while(1)
    {
        cin>>h>>m>>s>>k;
        if(h==0 && m==0 && k==0 && s==0)
            break;
        c.set(h,m,s);
        c = c + k;
        c.print();
    }
    return 0;
}

7-5 分数加法运算重载

相信同学们对复数运算符重载已经相当熟悉啦,那今天那我们来看看分数又该如何处理呢?定义一个分数类FS,有私有成员分子fz,分母fm。另有公有成员函数FS operator + (const FS &f)对运算符“+”进行重载,实现两个分数相加。题目首先给出一个整型数n,紧跟着2n行输入,输入形如3z4m,代表分子为3,分母为4。其中分母不为0,输入时分母可以为负数,但输出时分母必须为正数。
要求对分数进行两两求和,并化简。(备注说明:分数为0时,表示成0z1m,如果结果为负数,那么分子取负数,分母为正数)

示例如下:

输入:

3

4z9m

2z9m

4z5m

5z4m

2z-5m

1z-5m

输出:

2z3m

41z20m

-3z5m

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

int gcd(int a, int b)
{
	if (a % b == 0)
		return b;
	else
		return gcd(b, a % b);
}

class FS
{
	private:
		int fz, fm;
	public:
		friend int gcd(int a, int b);
		void set(int z, int m)
		{
			fz = z;
			fm = m;
		}
		FS operator + (const FS &f)
		{
			FS ff;
			int ffm, ffz;
			ffm = f.fm * fm;
			ffz = fz * f.fm + fm * f.fz;
			int t = gcd(ffz, ffm);
			ffz /= t;
			ffm /= t;
			if (ffm < 0)
			{
				ffm = -ffm;
				ffz = -ffz;
			}
			ff.set(ffz, ffm);
			return ff;
		}
		void display()
		{
			cout << fz << "z" << fm << "m" << endl;
		}
};

int main()
{
	int n, i;
	cin >> n;
	for (i = 0; i < n; i++)
	{
		FS fs1, fs2, fs3;
		int z, m;
		char z1, m1;
		cin >> z >> z1 >> m >> m1;
		fs1.set(z, m);
		cin >> z >> z1 >> m >> m1;
		fs2.set(z, m);
		fs3 = fs1 + fs2;
		fs3.display();
	}
	return 0;
}

7-6 计算时间相减

题目描述:定义一个时间类,小时和分钟是其两个私有成员数据。输入一个起始时间和一个结束时间(起始时间早于结束时间),通过运算符重载-(减号),计算这两个时间相隔多少分钟。说明:这两个时间在同一天之内,且采用24小时计时分式,即从00:00-23: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>
#include<cmath>
using namespace std;

class Time 
{
private:
	int hour,minute;
public:
	Time(int h = 0, int m = 0):hour(h),minute(m){}
	friend int operator- (Time t1, Time t2)
    {
        return t2.hour * 60 + t2.minute - t1.hour * 60 - t1.minute;
    }
};

int main()
{
    int h1,h2,m1,m2;
    while(1)
    {
        cin>>h1>>m1>>h2>>m2;
        if(h1==0 && h2==0 && m1==0 && m2==0)
            break;
        else
        {
            Time a1(h1,m1),a2(h2,m2);
            cout<<a1-a2<<endl;
        }
    }
}

7-7 分钟秒钟的时间相减

题目描述:
定义一个时间类,分钟和秒钟是其两个私有成员数据。输入一个起始时间和一个结束时间(起始时间早于结束时间),通过运算符重载-(减号),计算这两个时间相隔多少秒钟。说明:这两个时间在同一小时之内,且采用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>
#include<cmath>
using namespace std;

class Time 
{
private:
	int minute,second;
public:
	Time(int m = 0, int s = 0):second(s),minute(m){}
	friend int operator- (Time t1, Time t2)
    {
        return t2.minute * 60 + t2.second - t1.minute * 60 - t1.second;
    }
};

int main()
{
    int s1,s2,m1,m2;
    while(1)
    {
        cin>>m1>>s1>>m2>>s2;
        if(s1==0 && s2==0 && m1==0 && m2==0)
            break;
        else
        {
            Time a1(m1,s1),a2(m2,s2);
            cout<<a1-a2<<endl;
        }
    }
}

 

7-8 复数相乘--运算符重载

建立一个复数类Complex,实数和虚数是其私有数据成员;
建立复数类的无参和参数化构造函数;
建立一个 *(乘号)的运算符重载,以便于对两个复数直接进行乘法运算;
建立输出函数void display(),对复数进行输出;
主函数里定义三个复数类对象c1、c2、c3.
输入格式:
输入一共一行,每行两个复数,分别为复数类c1和c2。
输出格式:
执行c3=c1*c2运算之后,调用display函数,对c3进行输出。
提示:输入或输出的复数,可能只包含实部或虚部。

输入样例:
1+2i 2+3i
输出样例:
-4+7i

#include<bits/stdc++.h>
using namespace std;
class Complex
{
    int r,i;
public:
    Complex(){}
    Complex(int a,int b):r(a),i(b){}
    Complex operator *(Complex a)
    {
        Complex b;
        b.r = this->r * a.r - this->i * a.i;
        b.i = this->i * a.r + this->r * a.i;
        return b;
    }
    void display()
    {
        if(i > 0)
        {
            if(i == 1)
            {
                if(r == 0)
                    cout<<"i"<<endl;
                else
                    cout<<r<<"+"<<"i"<<endl;
            }
            else
            {
                if(r == 0)
                    cout<<i<<"i"<<endl;
                else
                    cout<<r<<"+"<<i<<"i"<<endl;
            }
        }
        else if(i < 0)
        {
            if(i == -1)
            {
                if(r != 0)
                    cout<<r;
                cout<<"-i"<<endl;
            }
            else
            {
                if(r == 0)
                    cout<<i<<"i"<<endl;
                else
                    cout<<r<<i<<"i"<<endl;
            }
        }
        else
            cout<<r<<endl;
    }
};

int main()
{
    Complex a[2];
    string str[2];
    for(int i = 0;i < 2;i++)
    {
        cin>>str[i];
        int v1,v2;
        if(str[i][str[i].length()-1]!='i')
        {//只有实部
            v2=0;
            if(str[i][0]=='-')    v1=-(atoi(str[i].substr(1).c_str()));
            else    v1=atoi(str[i].substr(0).c_str());
        }
        else
        {//有虚部
            int flagz = 0,flagf = -1;
            for(int j = 0;j < str[i].length();j++)
            {
                if(str[i][j] == '+')    flagz=j;
                if(str[i][j] == '-')    flagf=j;
            }
            if(flagz==0 && flagf==-1)
            {//没+也没-,只有正虚部 
                v1=0;
                if(str[i]=="i")    v2=1;
                else    v2 = atoi(str[i].substr(0,str[i].length()-1).c_str());
            }
            else if(flagz==0&&flagf==0)
            {//没+且-在首位,只有负虚部
				v1=0; 
				if(str[i]=="-i")    v2=-1;
				else    v2 = -(atoi(str[i].substr(1,str[i].length()-2).c_str()));
			}
            else
            {
				if(flagz)
                {
					//有+,+前的是实部,虚部为正 
					if(str[i][0]=='-')	v1=-atoi(str[i].substr(1,flagz-1).c_str());
					else	v1=atoi(str[i].substr(0,flagz).c_str());
					if(str[i][flagz+1]=='i')	v2=1;
					else	v2=atoi(str[i].substr(flagz+1,str[i].length()-2-flagz).c_str());
				}
                else if(flagf>0)
                {
					//出现-且不在首位,-前是实部,虚部为负
					if(str[i][0]=='-')	v1=-atoi(str[i].substr(1,flagf-1).c_str());
					else	v1=atoi(str[i].substr(0,flagf).c_str());
					if(str[i][flagf+1]=='i')	v2=-1;
					else	v2=-atoi(str[i].substr(flagf+1,str[i].length()-flagf-2).c_str());
				}
			}
        }
        a[i] = Complex(v1,v2);
    }
    (a[0] * a[1]).display();
    return 0;
}

7-9 矩阵的乘法运算

线性代数中的矩阵可以表示为一个row*column的二维数组,当row和column均为1时,退化为一个数,当row为1时,为一个行向量,当column为1时,为一个列向量。
建立一个整数矩阵类matrix,其私有数据成员如下:

int row;
int column;
int **mat;

建立该整数矩阵类matrix构造函数;
建立一个 *(乘号)的运算符重载,以便于对两个矩阵直接进行乘法运算;
建立输出函数void display(),对整数矩阵按行进行列对齐输出,格式化输出语句如下:

cout<<setw(10)<<mat[i][j];

主函数里定义三个整数矩阵类对象m1、m2、m3.
###输入格式:
分别输入两个矩阵,分别为整数矩阵类对象m1和m2。
每个矩阵输入如下:
第一行两个整数 r c,分别给出矩阵的行数和列数
接下来输入r行,对应整数矩阵的每一行
每行输入c个整数,对应当前行的c个列元素
###输出格式:
整数矩阵按行进行列对齐(宽度为10)后输出
判断m1和m2是否可以执行矩阵相乘运算。
若可以,执行m3=m1*m2运算之后,调用display函数,对m3进行输出。
若不可以,输出"Invalid Matrix multiplication!"
提示:输入或输出的整数矩阵,保证满足row>=1和column>=1。

输入样例:

4  5
1 0 0 0 5
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
5  5
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 8 9
5 6 7 8 9

输出样例:

        26        32        38        44        50
         4         6         8        10        12
         9        12        15        18        21
        16        20        24        32        36
#include <iostream>
#include <iomanip>
using namespace std;

class matrix
{
	private:
		int row;
		int column;
		int **mat;        //mat作为指针来表示数组
	public:
		matrix(int a = 0, int b = 0): row(a), column(b) {};
		void getmatrix(int a, int b)
		{
			int i, j;
			row = a, column = b;
			mat = new int *[a+2];
			for (i = 0; i < a+2; i++)
				mat[i] = new int[b+2];
			for (i = 0; i < row; i++)
				for (j = 0; j < column; j++)
					cin >> mat[i][j];
		}
		void display()
		{
			int i, j;
			for (i = 0; i < row; i++)
			{
				for (j = 0; j < column; j++)
					cout << setw(10) << mat[i][j];
				cout << endl;
			}
		}
		friend bool judge(const matrix &a,const matrix &b)
		{
			if (a.column == b.row || (a.column == 1 && a.row == 1))
				return true;
			else
				return false;
		}
		friend matrix operator*(const matrix &a,const matrix &b)
		{
			matrix c;
			int i, j, k, sum = 0;
			if (a.row == 1 && a.column == 1)
			{
				c.row = b.row;
				c.column = b.column;
				c.mat = new int *[b.row+2];
				for (i = 0; i < b.row+2; i++)
					c.mat[i] = new int[b.column+2];
				for (i = 0; i < b.row; i++)
					for (j = 0; j < b.column; j++)
						c.mat[i][j] = a.mat[0][0] * b.mat[i][j];
			}
			else
			{
				c.row = a.row;
				c.column = b.column;
				c.mat = new int*[a.row+2];
				for (i = 0; i < a.row+2; i++)
					c.mat[i] = new int[a.column+2];
				for (i = 0; i < a.row; i++)
				{
					for (j = 0; j < b.column; j++)
					{
						for (k = 0; k < a.column; k++)
						{
							sum += a.mat[i][k] * b.mat[k][j];
						}
						c.mat[i][j] = sum;
						sum = 0;
					}
				}
			}
			return c;
		}
};

int main()
{
	matrix m1, m2, m;
	int r, c;
	cin >> r >> c;
	m1.getmatrix(r, c);
	cin >> r >> c;
	m2.getmatrix(r, c);
	if (judge(m1, m2))
	{
		m = m1 * m2;
		m.display();
	}
	else
		cout << "Invalid Matrix multiplication!" << endl;
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoyangiii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值