本题要求编写程序,计算 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
分析 :
本题要实现的功能主要为呈现有理数,通过自定义函数将计算因子与结果都呈现出最终形式
有理数的输出优先级:Inf>0>(- )>整数部分>分式部分
测试点分析在代码里
呈现逻辑 (现假设a为分子,b为分母)
#include <stdio.h>
#include <stdlib.h>
long long z, a1, b1, a2, b2, cet = 0, mark = 1, x = 0;
char fuhao[13] = { '\0', '+','=','\n', '-', '=', '\n', '*', '=', '\n', '/', '=', '\n', };
int show(long long a, long long b) {
z = mark = 0;
if (a < 0 || b < 0)mark = 1;//mark用于标记负数
//当x=1(即正在进行乘法和除法的结果呈现)且a和b的符号相同时,该有理数为正数
if ((a < 0 ? 1 : 0) == (b < 0 ? 1 : 0) && x)x = mark = 0;
//将a,b都转换为正数,确保最大公约数的正确计算
a = abs(a); b = abs(b);
//除第一次show函数调用外的每次调用,均输出非有理数部分
(cet) ? (cet % 3) ? printf(" %c ", fuhao[cet++]) : printf("%c", fuhao[cet++]) : cet++;
//若a或者b为0,输出对应内容后则返回
if (((!b) ? printf("Inf") : ((!a) ? printf("0") : 0)))return 1;
/*GCD最大公约数,BD被除数(需为long long型,在求GCD过程中可能会超出整形范围,节点2,3会出
错),下面采用欧几里得算法计算GCD*/
long long GCD = a < b ? a : b, tmp;
long long BD = a > b ? a : b;
for (; tmp = BD % GCD; BD = GCD, GCD = tmp);
a /= GCD;
b /= GCD;
//分式a/b已为最简形式
//下面将最简分式拆分成整数(如果有)和分式部分
(a > b) ? ((z = a / b) ? a -= b * z : a -= b * z) : ((a == b)? a = b = z++: 0) ;
//输出有理式的最终形式
if (mark)printf("(-");
if (z)(a) ? printf("%lld ", z) : printf("%lld", z);
if (a)printf("%lld/%lld", a, b);
if (mark)printf(")");
return 1;
}
int main() {
scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);
show(a1, b1); show(a2, b2); show(a1 * b2 + a2 * b1, b1 * b2);//加法
show(a1, b1); show(a2, b2); show(a1 * b2 - a2 * b1, b1 * b2);//减法
show(a1, b1); x = show(a2, b2); show(a1 * a2, b1 * b2);//乘法
show(a1, b1); x = show(a2, b2); show(a1 * b2, b1 * a2);//除法
}