本题要求编写程序,计算 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/3
和2 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;
}