# include <iostream>
# include <cmath>
# include <climits>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
return b==0 ? a : gcd(b, a % b);
}
struct Fraction
{
ll up;
ll down;
Fraction() = default;
// 化简和矫正函数(我觉得最重要的是这个)
void reducion(){
// 因为当分子为0时,所求的最大公因数是分母本身,所以分母会自动变成1,不用自行额外矫正
//(当分子为0时,使分母为1方便运算)
ll t = gcd(abs(up), down);
up /= t;
down /= t;
// 让分母永远是正的,负号永远在分子上
if(down < 0){
up = -up;
down = -down;
}
}
Fraction(ll u, ll d){
up = u;
down = d;
reducion();
}
Fraction(const Fraction &ob){
up = ob.up;
down = ob.down;
reducion();
}
// 这个没用,但我以为函数返回局部对象(或匿名对象),会调用这个,或者拷贝构造函数,
// 但其实都不会,看了文章,这算编译器的优化吧,但还是写了保险点)
Fraction & operator=(const Fraction & rhs){
up = rhs.up;
down = rhs.down;
reducion();
return *this;
}
// 加
Fraction operator+(const Fraction & b){
Fraction c;
c.up = this->up*b.down + b.up*this->down;
c.down = this->down * b.down;
return Fraction(c); // 构造函数里有化简,这样就可以返回一个化简了的分数了
}
// 减
Fraction operator-(const Fraction & b){
Fraction c;
c.up = this->up*b.down - b.up*this->down;
c.down = this->down * b.down;
return Fraction(c);
}
// 乘
Fraction operator*(const Fraction & b){
Fraction c;
c.up = this->up * b.up;
c.down = this->down * b.down;
return Fraction(c);
}
// 除
Fraction operator/(const Fraction & b){
Fraction c;
c.up = this->up * b.down;
c.down = this->down * b.up;
return Fraction(c);
}
};
// 重载输出流<<运算符
ostream & operator<<(ostream & out, const Fraction & f)
{
// 分子为0输出0
if(f.up == 0)
out << 0;
// 分母为0输出Inf
else
if(f.down == 0)
out << "Inf";
// 输出真分数
else
if(abs(f.up) < f.down)
if(f.up >= 0)
out << f.up << "/" << f.down;
else
out << "(" << f.up << "/" << f.down << ")";
// 输出整数
else
if(f.up % f.down == 0)
if(f.up >=0)
out << f.up / f.down;
else
out << "(" << f.up / f.down << ")";
// 输出假分数
else
if(f.up >= 0)
out << f.up/f.down << " " << abs(f.up - (f.up/f.down)*f.down) << "/" << f.down;
else
out << "(" << f.up/f.down << " " << abs(f.up - (f.up/f.down)*f.down) << "/" << f.down << ")";
return out;
}
int main()
{
ll upa, upb, downa, downb;
scanf("%lld/%lld %lld/%lld", &upa, &downa, &upb, &downb);
Fraction a(upa, downa);
Fraction b(upb, downb);
cout << a << " + " << b << " = " << a+b << endl;
cout << a << " - " << b << " = " << a-b << endl;
cout << a << " * " << b << " = " << a*b << endl;
cout << a << " / " << b << " = " << a/b << endl;
return 0;
}
[PAT nivel B, cálculo de fracciones, ejercicios de C ++] 1034 las cuatro operaciones aritméticas de números racionales (20 puntos)
Supongo que te gusta
Origin blog.csdn.net/MYMarcoreus/article/details/110825285
Recomendado
Clasificación