PAT 乙级 1034.有理数四则运算 C++/Java

题目来源

本题要求编写程序,计算 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

分析:

这题加减乘除都不难,比较麻烦的是怎么输出分数,要考虑的情况比较多

分数处理

在进行打印和计算前,先对分数进行化简

分子分母同除最大公约数的绝对值(因为有负数,要考虑绝对值)

打印分数

分正数、负数、0三种

a:分子

b:分母

1. 正数(a > 0)

情况1:a == b b == 1

这种都可以 直接输出 a

如果是a == b比如5/5, 3/3,这种在分数处理的时候就变成了1/1,所以直接输出 a 就好了



情况2:a > b

5/3, 7/3

用一个times保存左边的数字,变成1 2/32 1/3这样的数字

times = a / b

a = a - times * b

然后输出times a/b



情况3:a < b

直接输出a/b

2. 分数为0

输出0

3. 负数(a < 0)

注意有括号

注意有括号

注意有括号

情况1:a == b b == 1

这种都可以 直接输出 a

如果是a == b比如-5/5, -3/3,这种在分数处理的时候就变成了-1/1,所以直接输出(a) 就好了



情况2:(-1 * a) > b

比如:-5/3, -7/2

times = a / b

a = (-1 * a) % b

然后输出(times a/b)

注意有括号

加减乘除

都挺简单的,注意格式就好

除法需要注意一下

打印分数的逻辑是根据 分子是否大于零

也就是说,如果计算出来得到5/-3这样的分数

要让5/-3变成-5/3

5/3 ÷ -3/2
a1 = 5,  b1 = 3
a2 = -3, b2 = 2

a3 = a1 * b2 = 10
b3 = b1 * a2 = -9

这样得到的分数是 10/-9
要让它变成 -10/9

C++实现

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <stack>
#include <cmath>
#include <map>

using namespace std;



// 最大公约数
int gcd(long long x, long long y) {
    return y == 0 ? x : gcd(y, x%y);
}


// 约分
void handleNum(long long& a1, long long& b1) {
    long long gcd1 = gcd(abs(a1), abs(b1));
    a1 /= gcd1;
    b1 /= gcd1;
}

// 打印分数
void display(long long a, long long b) {
    long long times = 0; // 保存整数部分,5/3变成 1 2/3,保存1
    if (a > 0) {
        // 3/1
        if (b == 1) {
            printf("%lld", a);
        }
        // 5/3
        else if (a > b) {
            times = a / b;
            a -= b * times;
            printf("%lld %lld/%lld", times, a, b);
        }
        // 3/5
        else {
            printf("%lld/%lld", a, b);
        }
    }
    else if (a == 0) {
        // 0/3
        printf("0");
    }
    else {
        // 负数
        if (b == 1) {
            printf("(%lld)", a);
        }
        // -5/3
        else if (-1 * a > b) {
            times = a / b;
            a = (-1 * a) % b;
            printf("(%lld %lld/%lld)", times, a, b);
        }
        else {

            printf("(%lld/%lld)", a, b);
        }

    }
}

// 加法
void add(long long a1, long long b1, long long a2, long long b2) {
    display(a1, b1);
    printf(" + ");
    display(a2, b2);
    printf(" = ");
    long long a3 = a1 * b2 + a2 * b1;
    long long b3 = b1 * b2;
    handleNum(a3, b3);
    display(a3, b3);
    printf("\n");

}

// 减法
void sub(long long a1, long long b1, long long a2, long long b2) {
    display(a1, b1);
    printf(" - ");
    display(a2, b2);
    printf(" = ");

    long long a3 = a1 * b2 - a2 * b1;
    long long b3 = b1 * b2;
    handleNum(a3, b3);
    display(a3, b3);

    printf("\n");

}

// 乘法
void mul(long long a1, long long b1, long long a2, long long b2) {
    display(a1, b1);
    printf(" * ");
    display(a2, b2);
    printf(" = ");

    long long a3 = a1 * a2;
    long long b3 = b1 * b2;
    handleNum(a3, b3);
    display(a3, b3);

    printf("\n");
}

// 除法
void div(long long a1, long long b1, long long a2, long long b2) {
    display(a1, b1);
    printf(" / ");
    display(a2, b2);
    printf(" = ");
    long long a3 = a1 * b2;
    long long b3 = b1 * a2;
    if (a2 == 0) {
        printf("Inf");
        return;
    }

    if (b3 < 0) {
        a3 *= -1;
        b3 *= -1;
    }
    handleNum(a3, b3);
    display(a3, b3);
    printf("\n");
}


int main() {
    long long a1, b1;
    long long a2, b2;
    scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);
    handleNum(a1, b1);
    handleNum(a2, b2);
    add(a1, b1, a2, b2);
    sub(a1, b1, a2, b2);
    mul(a1, b1, a2, b2);
    div(a1, b1, a2, b2);

    return 0;
}
上一篇:BigDecimal除法方法divide()保留位问题


下一篇:autoware