/*
* 程序思路说明
* 1/3本身是两个数据进行运算的语句,如果要把它变成一个整体,
* 就需要定义Integer类和Fraction类,这样Fraction类定义的变量可以是 1/3这种形式。
* 1/3 + 1/2 = 5/6这种运算若要成立就需要对四则运算符进行重载(重新定义+ - * /四种运算方法)
* 重载运算符的思路:
* 输入运算符要想实现1/3和2/3进行运算的形式,输入运算符需要重载
* 如果分数相加,就要有通分的过程,重载加法运算符的时候就要把通分的算法写进去
* 减法也需要通分,所以和加法思路差不多
* 乘法的思路是分子乘分子,分母乘分母,然后再约分
* 除法思路是将被除数取倒数,然后再用乘法的思路
* 至于说输出也需要重载,真分数可以是最简分数的形式输出
* 对于假分数来说,分子比分母大,可以用带分数的形式输出
* 4/3三分之四可以写成 1 (3/1) 一又三分之一
* 程序思路说明完毕
*/
#include <iostream>
using namespace std;
class Integer //整数类 类名是Integer
{
public:
int nume; //定义分子,变量名是nume,来源于分子Numerator的缩写
int deno; //定义分母,变量名是deno,来源于分母denominator的缩写
int judge; //定义一个判断值,具体判断需看源码
Integer(int a = 0, int b = 1) :nume(a), deno(b) {}
//声明了一个构造函数,并传递了一个初始参数0和1,初始化分子nume为0,分母deno为1
~Integer() { } //声明了一个析构函数
void display(); //声明了这个显示函数
};
class Fraction :public Integer //分数类,进行输入输出 ,类名是Fraction
{
public:
Fraction(int a = 0, int b = 1) : Integer(a, b) { } //声明输入函数
Fraction operator+ (Fraction& c);
Fraction operator+ (int n);
Fraction operator- (Fraction& c);
Fraction operator- (int n);
friend Fraction operator-(int n, Fraction& c); //重载友元函数
Fraction operator* (Fraction& c);
Fraction operator* (int n);
Fraction operator/ (Fraction& c);
friend Fraction operator/(int n, Fraction& c);
Fraction operator / (int n);
Fraction predigest(); //约分函数
};
void Integer::display()//界面设计
{
cout << "\t\t\t\t分数计算器"<<endl;
cout << "**********************************************************************************\n" ;
cout << "* 请选择功能: *\n";
cout << "* A 分数与整数的四则运算 *\n";
cout << "* B 整数与分数的四则运算 *\n";
cout << "* C 分数与分数的四则运算 *\n";
cout << "* 0 输入0退出系统 *\n";
cout << "**********************************************************************************\n";
}
Fraction Fraction::predigest()//定义约分函数
{
int n, d, t, sign = 1;
Fraction temp; //定义一个在约分的时候的Fraction型变量temp
if (nume < 0 && deno < 0) //这是分子分母都为负的情况,负负得正,都把符号消掉
{
nume = -nume;
deno = -deno;
}
if (nume > 0 && deno < 0) //这里是分母是负的,分子是正的,整体值是负的,把负号存到sign里
{
deno = -deno; //因为负号已经存起来,所以取正便于运算。
sign = -1;
}
if (nume < 0 && deno > 0) //这里是分母是正的,分子是负的,整体值是负的,把负号存到sign里
{
nume = -nume;
sign = -1;
}
n = nume; //分子赋值给临时局部变量n
d = deno; //分母赋值给临时局部变量d
int r; //辗转相除求出最大公约数 ,临时变量r是交换的中间变量
//先用较小的数对较大的数取余,再用余数对较小的数求余,直到余数为零
if (n < d)
{ //因为后面的取余语句默认n是大的,所以万一n是小的,就将其值交换
t = n;
n = d; //这里其实可以用algorithm库里的swap函数实现。swap(n,d);就可以省三行
d = t;
}
r = n % d; //求一次余数
while (r != 0) //如果余数不等于0,就进行辗转相除法求最大公约数
{
n = d;
d = r;
r = n % d;
} //得到了d是最大公约数
temp.nume = sign * (nume / d); //此时分子除最大公约数,分母也除最大公约数,同时分子加上符号,再把值传回去。就实现了约分
temp.deno = deno / d; //分母也除以最大公约数,才能是约分后的分母
return temp; //把约分之后的结果传回去
}
Fraction Fraction::operator+(Fraction& c)//重载加法运算符
{
Fraction temp;
temp.nume = nume * c.deno + deno * c.nume;
temp.deno = deno * c.deno;
return temp;
}
Fraction Fraction::operator+ (int n)
{
Fraction temp;
temp.nume = deno * n + nume;
temp.deno = deno;
return temp;
}
Fraction Fraction::operator-(Fraction& c)//重载减法运算符
{
Fraction temp;
temp.nume = nume * c.deno - deno * c.nume;
temp.deno = deno * c.deno;
return temp;
}
Fraction Fraction::operator- (int n)
{
Fraction temp;
temp.nume = deno * n - nume;
temp.deno = deno;
return temp;
}
Fraction Fraction::operator*(Fraction& c)//重载乘法运算符
{
Fraction temp;
temp.nume = nume * c.nume; //分子乘分子分母乘分母
temp.deno = deno * c.deno; //先把结果传过去,约分最后用函数实现
return temp;
}
Fraction Fraction::operator*(int n)
{
Fraction temp;
temp.nume = nume * n;
temp.deno = deno;
return temp;
}
Fraction operator-(int n, Fraction& c)
{
Fraction temp;
temp.nume = c.deno * n - c.nume;
temp.deno = c.deno;
return temp;
}
Fraction Fraction::operator/(Fraction& c)//重载除法运算符
{
Fraction temp;
temp.nume = nume * c.deno; //取倒数(分子分母互换)
temp.deno = deno * c.nume; //再乘,就实现了除法
return temp;
}
Fraction Fraction::operator/ (int n)
{
Fraction temp;
temp.nume = nume;
temp.deno = deno * n;
return temp;
}
Fraction operator/(int n, Fraction& c)
{
Fraction temp;
temp.nume = n * c.deno;
temp.deno = c.nume;
return temp;
}
ostream& operator<<(ostream& output, Fraction& t)//重载输出运算符
{
int a, b, c;
a = t.nume;
b = t.deno;
if (a == 0 || b == 0)
cout << "0" << endl;
if (b == 1)
cout << a << endl;
if (a > b && b != 1)
{
c = a / b;
a = a % b;
cout << c;
cout << "又" << a << '/' << b; //带分数
}
if (a<0 && -a>b && b != 1)
{
c = -a / b;
a = -a % b;
c = -c;
cout << '=' << c;
if (a != 0)
cout << "又" << a << '/' << b;
}
if (t.nume > 0 && t.nume < t.deno && t.deno != 0 && t.deno != 1)
output << t.nume << '/' << t.deno << endl;
if (t.nume < 0 && -t.nume < t.deno && t.deno != 0 && t.deno != 1)
output << "(" << t.nume << '/' << t.deno << ")" << endl;
return output;
}
istream& operator>>(istream& input, Fraction& t)//重载输入运算符
{
int a, c;
char b;
input >> a >> b >> c;
if (b == '/' && c != 0)
{
t.nume = a;
t.deno = c;
t.judge = 0;
}
else
{
t.judge = 1;
cout << "输入格式错误或分母为0!请退出重新输入!" << endl;
}
return input;
}
int main()
{
Integer dis; //定义一个将来用来打印主界面的dis变量
Fraction fracNum, fracedNum, result, real;
/*
* 这里的一堆变量意义如下:
* fracNum(Fraction Number) 表示第一个数
* fracedNum(Fracted Number) 表示第二个数
* result 用来存结果
* real 用来存约分之后的真分数
*/
double m, z, n;
char oprt; //定义一个操作符,操作符可以是 + - * /
char selectValue; //定义一个选择值
dis.display(); //执行输出函数,把页面打印出来。
cout << "输入0,关闭系统,输入A,B,C进入" << endl;
cin >> selectValue; //输入选择
while (selectValue != '0')
{
cout << " 请输入:(A/B/C) :";
cin >> selectValue;
if (selectValue == 'A' || selectValue == 'a')//分数与正整数运算
{
do
{
cout << endl << " 请输入一个分数: ";
cin >> fracNum;
} while (fracNum.judge == 1);
cout << endl << " 请输入运算符: ";
cin >> oprt;
cout << endl << " 请输入一个整数: ";
cin >> z;
if (oprt == '+')
result = fracNum + z;
if (oprt == '-')
result = fracNum - z;
if (oprt == '*')
result = fracNum * z;
if (oprt == '/')
result = fracNum / z;
real = result.predigest(); //这里result并不是最后一步结果变量,约分之后的real才是最终输出的值
cout << " 运算时的规范形式为: " << fracNum << oprt << z << '=' << real << endl << endl;
}
if (selectValue == 'B' || selectValue == 'b')//正整数与分数运算
{
cout << endl << endl << " 请输入一个整数: ";
cin >> z;
cout << endl << " 请输入运算符: ";
cin >> oprt;
do
{
cout << endl << " 请输入一个分数: ";
cin >> fracedNum;
} while (fracedNum.judge == 1);
if (oprt == '+')
result = fracedNum + z;
if (oprt == '-')
result = fracedNum - z;
if (oprt == '*')
result = fracedNum * z;
if (oprt == '/')
result = fracedNum / z;
real = result.predigest();
cout << " 运算时的规范形势为: " << z << oprt << fracedNum << '=' << real << endl << endl;
}
if (selectValue == 'C' || selectValue == 'c')//分数与分数运算
{
do
{
cout << endl << " 请输入一个分数: ";
cin >> fracNum;
} while (fracNum.judge == 1);
cout << endl << " 请输入运算符: ";
cin >> oprt;
do
{
cout << endl << " 请输入一个分数: ";
cin >> fracedNum;
} while (fracedNum.judge == 1);
if (oprt == '+')
result = fracNum + fracedNum;
if (oprt == '-')
result = fracNum - fracedNum;
if (oprt == '*')
result = fracNum * fracedNum;
if (oprt == '/')
result = fracNum / fracedNum;
real = result.predigest();
cout << " 运算时的规范形势为: " << fracNum << oprt << fracedNum << '=' << real << endl << endl;
}
}
return 0;
}