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

来源:互联网 发布:会计常用电脑软件 编辑:程序博客网 时间:2024/05/17 04:25

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

Answer:

#include<iostream>#include<cmath>using namespace std;long long max_common_divisor(long long a, long long b) {    if (a % b == 0)        return abs(b);    return max_common_divisor(b, a % b);}struct fraq {    long long memb;    long long deno;    inline fraq() {}    inline fraq(long long t1, long long t2) {        this->memb = t1;        this->deno = t2;        this->abbreviation();    }    inline void expression() {        if(this->deno == 0) {            cout << "Inf";        } else if (this->memb == 0) {            cout << 0;        } else if (this->deno == 1) {            if (this->memb > 0)                cout << this->memb;            else                cout << '(' << this->memb << ')';        } else {            if (this->memb > 0)                if (this->memb > this->deno)                    this->complex_expression();                else                    this->simple_expression();            else {                cout << '(';                if (-this->memb > this->deno)                    this->complex_expression();                else                    this->simple_expression();                cout << ')';            }        }    }    inline void simple_expression() {        cout << this->memb << '/' << this->deno;    }    inline void complex_expression() {        long long z = this->memb / this->deno;        cout << z << ' ' << abs(this->memb - this->deno * z) << '/' << this->deno;    }    inline void abbreviation() {        if(this->deno == 0)            return;        long long mmd = max_common_divisor(this->memb, this->deno);        this->memb /= mmd;        this->deno /= mmd;        if(this->deno < 0) {            this->memb *= -1;            this->deno *= -1;        }    }};void get_fraq_from_expr(char* expr, fraq* f) {    int sym = 1;    int i = 0;    if (expr[i] == '-') {        sym = -1;        i++;    }    long long t1 = 0, t2 = 0;    for (; expr[i] != '/'; i++) {        t1 = t1 * 10 + expr[i] - '0';    }    for (++i; expr[i]; i++) {        t2 = t2 * 10 + expr[i] - '0';    }    *f = fraq(t1 * sym, t2);}void add(fraq* f1, fraq* f2, fraq* f3) {    f3->memb = f1->memb*f2->deno + f1->deno*f2->memb;    f3->deno = f1->deno*f2->deno;    f3->abbreviation();}void diff(fraq* f1, fraq* f2, fraq* f3) {    f3->memb = f1->memb*f2->deno - f1->deno*f2->memb;    f3->deno = f1->deno*f2->deno;    f3->abbreviation();}void multi(fraq* f1, fraq* f2, fraq* f3) {    f3->memb = f1->memb*f2->memb;    f3->deno = f1->deno*f2->deno;    f3->abbreviation();}void div(fraq* f1, fraq* f2, fraq* f3) {    f3->memb = f1->memb*f2->deno;    f3->deno = f1->deno*f2->memb;    f3->abbreviation();}int main() {    char input1[30];    char input2[30];    cin >> input1 >> input2;    fraq* f1 = new fraq();    fraq* f2 = new fraq();    get_fraq_from_expr(input1, f1);    get_fraq_from_expr(input2, f2);    void (*cals[4])(fraq* f1, fraq* f2, fraq* f3) = {        add,        diff,        multi,        div    };    char opers[4] = {'+','-','*','/'};    for(int i = 0;i < 4;i ++) {        f1->expression();        cout << ' ' << opers[i] << ' ';        f2->expression();        cout << " = ";        fraq f3;        cals[i](f1, f2, &f3);        f3.expression();        cout << '\n';    }}

PS.
又用到了函数指针。
最麻烦的地方是表达式的处理,分各种情况。不知道有没有简单的写法。
还有就是约分的时候有可能得到分母为负数的情况,后来处理掉了。
当然还有long long这个数据类型,本来以为long就够了。
然而并不够。

0 0
原创粉丝点击