1034 有理数四则运算 (20 分)
- 2019 年 10 月 5 日
- 筆記
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
【我的代码】
// 1034 有理数四则运算 (20 分).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <cstdio> using namespace std; //求最大公约数 int gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); } //打印一个数 void print(long long a_1, long long a_2) { long long b = 0; if (a_1 > 0) { //正数 if (a_2 == 1) cout << a_1; else if(a_1 > a_2){ //分子比分母大 b = a_1 / a_2; a_1 -= a_2 * b; cout << b << " " << a_1 << "/" << a_2; } else { //无需化简 cout << a_1 << "/" << a_2; } } else if (a_1 == 0) { cout << 0; } else { //负数 if (a_2 == 1) cout << "(" << a_1 << ")"; else if (-1 * a_1 > a_2) { b = a_1 / a_2; a_1 = (-1 * a_1) % a_2; cout << "(" << b << " " << a_1 << "/" << a_2 << ")"; } else { //无需化简 cout << "(" << a_1 << "/" << a_2 << ")"; } } } //减法 void sub(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "-" << " "; print(b_1, b_2); cout << " " << "=" << " ";; long long c_1 = a_1 * b_2 - a_2 * b_1; long long c_2 = a_2 * b_2; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } //加法 void add(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "+" << " "; print(b_1, b_2); cout << " " << "=" << " ";; long long c_1 = a_1 * b_2 + a_2 * b_1; long long c_2 = a_2 * b_2; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } //乘法 void mult(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "*" << " "; print(b_1, b_2); cout << " " << "=" << " ";; long long c_1 = a_1 * b_1; long long c_2 = a_2 * b_2; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } //除法 void div(long long a_1, long long a_2, long long b_1, long long b_2) { print(a_1, a_2); cout << " " << "/" << " "; print(b_1, b_2); cout << " " << "=" << " "; if (!b_1) { cout << "Inf"; return; } else if (b_1 < 0) { long long c_1 = -1 * a_1 * b_2; long long c_2 = -1 * a_2 * b_1; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } else { long long c_1 = a_1 * b_2; long long c_2 = a_2 * b_1; long long c = abs(gcd(c_1, c_2)); c_1 /= c; c_2 /= c; print(c_1, c_2); } } int main() { //输入 long long a_1, a_2, b_1, b_2; scanf_s("%lld/%lld %lld/%lld", &a_1, &a_2, &b_1, &b_2); //把a,b化到最简 long long num_1 = abs(gcd(a_1, a_2));//得到a的最大公约数 a_1 /= num_1; a_2 /= num_1; long long num_2 = abs(gcd(b_1, b_2));//得到b的最大公约数 b_1 /= num_2; b_2 /= num_2; //计算 add(a_1, a_2, b_1, b_2); cout << endl; sub(a_1, a_2, b_1, b_2); cout << endl; mult(a_1, a_2, b_1, b_2); cout << endl; div(a_1, a_2, b_1, b_2); return 0; }
【思路】
- 所有的数都要是化简后的,因此需要单独分离一个函数作为化简函数,这里参考了辗转相除法,找到最大公约数,然后分子分母同时除最大共约数,得到最简化的分式。
- 发现数字化简到分式后还要化成分子比分母小的形式(忘记怎么叫了),因此这里需要一个格式转换函数,就写了一个print函数,对分子大于0,小于0和等于0进行讨论。
- +、-、*都是直接对分子分母进行操作,这里不需要考虑化简问题,因为我们有单独出来的化简函数。而除法需要注意!!Inf的情况。