分数计算--PAT.A1081. Rational Arithmetic

来源:互联网 发布:测试本机端口是否开放 编辑:程序博客网 时间:2024/06/11 03:43
/**********************3stone***************************Problem: PAT.A1081. Rational Arithmetic (20) Author:3stoneTime:2017/3/6 要求: 1、带分数若为负值,则整数部分为负,分数部分为正, 2、负数参与运算或作为结果都要带括号  3、除0时,输出Inf   思路: 1、设置分数结构体,读入时把分子分母按格式分开读入 2、求最小公倍数,进行通分(分子分母同时乘以倍数)    【正好复习一下最大公约数&最小公倍数的做法】  3、加减可以一起做;乘法对应相乘之后约分;除法颠倒分子分母当做乘法计算 【数据范围为int,因此相乘最大可达long long,所以用int会有一组数据溢出】 ***********************3stone***************************/#include<cstdio>#include<algorithm>using namespace std;struct ND{    long long number, domen;//分子分母     long long integ; //整数部分 }; long long getMax(long long a, long long b){//最大公约数         if(0 == b) return a;    else return getMax(b, a%b);} long long getMin(long long a, long long b){//最小公倍数     return (a*b) / getMax(a, b);}//加法运算 ND add(ND a, ND b){    long long domen = getMin(a.domen, b.domen);    long long number = a.number*(domen/a.domen) + b.number*(domen/b.domen);     ND c;    //约分    int temp = getMax(number < 0 ? (-1)*number : number, domen);    //求最大公约数时注意分子可能是负数     c.number = (number / temp);    c.domen = (domen / temp);    return c;}//减法运算 ND mus(ND a, ND b){    b.number = (-1) * b.number;//转加法     return add(a, b);} //乘法运算 ND mul(ND a, ND b){    long long number = a.number*b.number;    long long domen = a.domen*b.domen;      long long temp = getMax(abs(number), domen);    ND c;    c.number = number / temp;    c.domen = domen / temp;    return c; } //除法运算 ND quot(ND a, ND b){    long long temp = b.number;//注意颠倒分子分母时,若有负号要处理     if(temp < 0){        b.number = (-1)*b.domen;        b.domen = (-1)*temp;        }    else{        b.number = b.domen;        b.domen = temp;    }    return mul(a, b);//转乘法 } //输出分数 void showResult(ND a){    //约分     long long temp = getMax(abs(a.number), a.domen);    a.number = a.number / temp;    a.domen = a.domen / temp;    //    a.integ = a.number/a.domen;    a.number = a.number%a.domen;//涉及负数求模[复习]    if(a.integ != 0){        if(0 == a.number){//只有整数部分             if(a.integ < 0) printf("(%lld)", a.integ);            else printf("%lld", a.integ);        }        else if(a.integ < 0 && a.number < 0){//带分数             a.number *= (-1);             printf("(%lld %lld/%lld)", a.integ, a.number, a.domen);        }         else            printf("%lld %lld/%lld", a.integ, a.number, a.domen);    }    else if(a.number < 0)//分子<0         printf("(%lld/%lld)", a.number, a.domen);    else if(0 == a.number)//分子为0         printf("%lld", a.number);    else //分子>0         printf("%lld/%lld", a.number, a.domen);    //假分数要化成带分数, 若为负值,只在整数部分前加负号即可          //负数要带括号;}int main(){    ND a, b;    while(scanf("%lld/%lld %lld/%lld",&a.number,&a.domen,&b.number,&b.domen) != EOF){        //加法         showResult(a);        printf(" + ");        showResult(b);        printf(" = ");         ND c = add(a, b);        showResult(c);        printf("\n");        //减法         showResult(a);        printf(" - ");        showResult(b);        printf(" = ");         c = mus(a, b);        showResult(c);        printf("\n");        //乘法         showResult(a);        printf(" * ");        showResult(b);        printf(" = ");         c = mul(a, b);        showResult(c);        printf("\n");        //除法         showResult(a);        printf(" / ");        showResult(b);        printf(" = ");         if(0 == b.number){//除数为零             printf("Inf\n");        }           else{            ND c = quot(a, b);            showResult(c);            printf("\n");        }    }//while    return 0;} 
0 0