本题要求编写程序,计算 2 个有理数的和、差、积、商。
输入在一行中按照 a1/b1 a2/b2
的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。
分别在 4 行中按照 有理数1 运算符 有理数2 = 结果
的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b
,其中 k
是整数部分,a/b
是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf
。题目保证正确的输出中没有超过整型范围的整数。
2/3 -4/2
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
5/3 0/6
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
(反思:虽然这次写的时间挺长的,不过相比之前的一些花了大部分时间debug模拟题来说花的时间还算短的。我认为,要想花更少的时间在debug上,很关键的一个因素就是思路要清晰。那如何做到思路清晰呢?袁教授在第一个学期告诉我们“一定要写”——把思路都写下来,可以画流程图(虽然我不是很习惯,而且也不会)、也可以分条写思路,这样尽管有时候会稍微耗点时间,思路对了,写的时候也就快了(至少基本不用debug),减少自闭时间。)
思路:1、用3个long long存储输入的两个数的分母分子。2、用6个char数组存储简化之后的因子和4个结果。3、写一个自定义sim函数,用来简化分数。
#include
#include
#include
using namespace std;
const int maxn = 100;
char res1[maxn], res2[maxn], ans1[maxn], ans2[maxn], ans3[maxn], ans4[maxn];//存储输出的各个简化之后的分数
long long A1, B1, A2, B2;//存储输入分子、分母、分子、分母(包括符号)
void sum(long long a1, long long b1, long long a2, long long b2, char temp[])//参数分别是运算数1的分子、分母,运算数2的分子、分母,temp存储了未约分的结果(最后在main函数中会统一对其简化)
{
sprintf(temp, "%lld/%lld", a1 * b2 + a2 * b1, b1 * b2);
}
void mul(long long a1, long long b1, long long a2, long long b2, char temp[])
{
sprintf(temp, "%lld/%lld", a1 * a2, b1 * b2);
}
long long gcd(long long a, long long b)
{
return !b ? a : gcd(b, a % b);
}
void sim(char s[], char res[]);
int main()
{
char temp[maxn];
char s1[maxn], s2[maxn];
scanf("%s%s", s1, s2);
sscanf(s1, "%lld/%lld", &A1, &B1);
sscanf(s2, "%lld/%lld", &A2, &B2);//获取 A1, B1, A2, B2;
sim(s1, res1), sim(s2, res2);//化简输入的因子;
sum(A1, B1, A2, B2, temp), sim(temp, ans1);
sum(A1, B1, -A2, B2, temp), sim(temp, ans2);
mul(A1, B1, A2, B2, temp), sim(temp, ans3);
if(A2 != 0) mul(A1, B1, A2 / abs(A2) * B2, abs(A2), temp), sim(temp, ans4);
printf("%s + %s = %s\n", res1, res2, ans1);
printf("%s - %s = %s\n", res1, res2, ans2);
printf("%s * %s = %s\n", res1, res2, ans3);
printf("%s / %s = %s\n", res1, res2, !A2 ? "Inf" : ans4);
return 0;
}
void sim(char s[], char res[])
{
char temp[maxn];
long long a, b, mgcd;
sscanf(s, "%lld/%lld", &a, &b);
mgcd = gcd(abs(a), b);//求得最大公约数(正数)
a /= mgcd, b /= mgcd;//约分
if(a / b)//判断是否有整数位
{
sprintf(temp, "%lld", a / b);
if(a % b)//判断是否有分数
sprintf(&temp[strlen(temp)], " %lld/%lld", abs(a % b), b);
}
else
{
if(a % b)//判断是否有分数
sprintf(temp, "%lld/%lld", a, b);
else sprintf(temp, "%lld", 0);//只有0的情况
}
if(temp[0] == '-')//最后处理一哈加括号()的问题
sprintf(res, "(%s)", temp);
else sprintf(res, "%s", temp);
}