PAT 乙级 1034 有理数四则运算 (精简代码)+ (测试点分析)+(详细注释)

本题要求编写程序,计算 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);//除法
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值