[PAT nivel B, cálculo de fracciones, ejercicios de C ++] 1034 las cuatro operaciones aritméticas de números racionales (20 puntos)

# 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;
}

Supongo que te gusta

Origin blog.csdn.net/MYMarcoreus/article/details/110825285
Recomendado
Clasificación