1034. 有理数四则运算(20)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1034. 有理数四则运算(20)相关的知识,希望对你有一定的参考价值。

本题要求编写程序,计算2个有理数的和、差、积、商。

输入格式:

输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。

输出格式:

分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。

输入样例1:

2/3 -4/2
输出样例1:
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
输入样例2:
5/3 0/6
输出样例2:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
 
这道题费了我很长时间才AC,明明看上去很简单,但是实际做了一下,才发现其中的深坑。刚开始我用面向过程的思维去做,写到第四个嵌套if-else的时候就感觉代码结构不太好了,于是用面向对象的思路去解开了它,代码可读性也变得比之前好了,下面是我的代码:
//1034
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;

long long cfact(long long a, long long b)

{
    long long min = a > b ? b : a;
    long long max = a < b ? b : a;
    long long tmp = max%min;
    while (tmp)
    {
        max = min;
        min = tmp;
        tmp = max%min;
    }
    long long result = min > 0 ? min : -min;
    return result;
}

struct fraction
{
    long long mem;
    long long den;
    long long thd = 0;
    long long sim()
    {
        if (mem == 0)
        {
            thd = 0;
            return 1;
        }
        else if (den == 0)
        {
            return -1;
        }
        else if (mem%den == 0)
        {
            thd = mem / den;
            return 1;
        }
        else {
            thd = mem / den;
            long long cf = cfact(mem, den);
            if (thd != 0) {
                mem = ((mem%den)>0?mem%den:-(mem%den))/ cf;
            }
            else {
                mem = mem / cf;
            }
            den = den /cf;
            if (den < 0) {
                den = -den;
                mem = -mem;
            }
            return 0;
        }

    };
    friend fraction operator+(fraction &f1,fraction &f2);    
    friend fraction operator-(fraction &f1,fraction &f2);    
    friend fraction operator*(fraction &f1,fraction &f2);    
    friend fraction operator/(fraction &f1,fraction &f2);    

    string Show()
    {
        string res;
        long long tmp = sim();
        if (tmp == 1)
            if (thd < 0)
                res = "(" + to_string(thd) + ")";
                //printf("(%lld)",thd);
            else {
                res = to_string(thd);
                //printf("%lld", thd);
            }
        else if (tmp == -1)
        {
            res ="Inf";
        }
        else {
            if (thd == 0)
            {
                if (mem < 0)
                    res = ( + to_string(mem) + / + to_string(den) + );
                //printf("(%lld/%lld)", mem, den);
                else
                    res = to_string(mem) + / + to_string(den);
                    //printf("%lld/%lld", mem, den);
            }
            else {
                if (thd < 0)
                    //    printf("(%lld %lld/%lld)", thd, mem, den);
                    res = ( + to_string(thd) +   + to_string(mem)+ / + to_string(den)+ );
                else
                    res = to_string(thd) +   + to_string(mem) + / + to_string(den) ;
                //    printf("%lld %lld/%lld",thd,mem,den);
            }
        }
        return res;
    }
};
fraction operator+(fraction &f1, fraction &f2)
{
    long long cf = cfact(f1.den, f2.den);
    long long cm = cf*(f1.den / cf)*(f2.den / cf);
    fraction result;
    result.mem = f1.mem*(cm/f1.den) + f2.mem*(cm/f2.den);
    result.den = cm;
    return result;
}
fraction operator-(fraction &f1, fraction &f2)
{
    long long cf = cfact(f1.den, f2.den);
    long long cm = cf*(f1.den / cf)*(f2.den / cf);
    fraction result;
    result.mem = f1.mem*(cm / f1.den) - f2.mem*(cm / f2.den);
    result.den = cm;;
    return result;
}
fraction operator*(fraction &f1, fraction &f2)
{
    fraction result;
    result.mem = f1.mem * f2.mem;
    result.den = f1.den * f2.den;
    return result;
}
fraction operator/(fraction &f1, fraction &f2)
{
    fraction result;
    result.mem = f1.mem * f2.den;
    result.den = f1.den * f2.mem;
    return result;
}


int main()
{
    fraction f1;
    fraction f2;
    fraction result1,result2,result3,result4;
    scanf("%lld/%lld %lld/%lld",&f1.mem,
        &f1.den,&f2.mem,&f2.den);
    result1 = f1 + f2;
    result2 = f1 - f2;
    result3 = f1 * f2;
    result4 = f1 / f2;
    string f1_str = f1.Show();
    string f2_str = f2.Show();
    string res1_str = result1.Show();
    string res2_str = result2.Show();
    string res3_str = result3.Show();
    string res4_str = result4.Show();
    //f1.Show();
    cout << f1_str << " + " << f2_str << " = " << res1_str<<endl;
    cout << f1_str << " - " << f2_str << " = " << res2_str<<endl;
    cout << f1_str << " * " << f2_str << " = " << res3_str<<endl;
    cout << f1_str << " / " << f2_str << " = " << res4_str<<endl;
    /*
    printf(" + ");
    f2.Show();
    printf(" = ");
    result1.Show();
    printf("\n");
    f1.Show();
    printf(" - ");
    f2.Show();
    printf(" = ");
    result2.Show();
    printf("\n");

    f1.Show();
    printf(" * ");
    f2.Show();
    printf(" = ");
    result3.Show();
    printf("\n");
    f1.Show();
    printf(" / ");
    f2.Show();
    printf(" = ");
    result4.Show();
    printf("\n");*/
    return 0;
}
在处理被除数为0的情况,我本以为C++自带的<stdexcept>库提供这种异常处理,然而好像C++无法处理这种情况,要自己写异常类,于是我只能另想办法去处理这种情况了,如果是C#或者Java,应该可以很方便地处理它把。

以上是关于1034. 有理数四则运算(20)的主要内容,如果未能解决你的问题,请参考以下文章

PAT1034 有理数四则运算 (20分)

1034. 有理数四则运算(20)

1034 有理数四则运算 (20分)

PAT乙级1034. 有理数四则运算(20)

PAT乙级1034 有理数四则运算 (20 分)

PAT乙级1034