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

问题分析:

题目不算太难,就是写起来有点的繁琐,感觉按顺序排下来,PAT乙级的倒数第二题写起来都挺繁琐的。

题目考察的要点及坑点主要有:

1)用scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);读入的方式,将2个分数的分子和分母的数值取出来。

2)坑的地方在于题目说了整数部分没超出整型范围,但是加个负号,就超了,这题故意说了不超整型范围,本质是考察带负号的情况的,所以在定义数字时要用long long类型去定义

3)另外一个难点在于求解最大公约数,要用辗转相除的方法求解,这个C++好像没提供函数,就自己写一个函数。

这题我的思路是写一个函数,入参是分子和分母,然后以字符串的形式输出参数最终的结果。代码的核心内容就是这个函数的处理,要考虑的全面一些。

代码:

#pragma warning(disable:4996)
#include <stdio.h>
#include <string>
#include <math.h>
using namespace std;

int gcd(int a, int b)//求最大公约数 
{
	if (a < b)
		swap(a, b);
	if (a % b == 0)
		return b;
	else 
		gcd(b, a % b);
}

string Simply(long long a, long long b)//输入分子分母,返回标准输出格式
{
	string str;
	if (b == 0)//分母为0,直接返回Inf
		return str = "Inf";

	if (a * b < 0 && b < 0)//把负号放在分子上
	{
		a *= -1;
		b *= -1;
	}

	long long c = a / b;
	a = a % b;
	if (a < 0 && c < 0)
		a *= -1;

	if (a != 0)
	{
		int i = gcd(fabs(a), fabs(b));
		a /= i;
		b /= i;
	}
	//根据不同的情况,输出不同的格式:
	if (c < 0)
	{
		if (a == 0)
			str = "(" + to_string(c)+")";
		else
			str = "(" + to_string(c) + " " + to_string(a) + "/" + to_string(b) + ")";
	}
	else if (c == 0)
	{
		if (a == 0)
			str = "0";
		else if (a > 0)
			str = to_string(a) + "/" + to_string(b);
		else
			str = "(" + to_string(a) + "/" + to_string(b) + ")";
	}
	else
	{
		if (a > 0)
			str = to_string(c) + " " + to_string(a) + "/" + to_string(b);
		else
			str = to_string(c);
	}
	return str;
}

int main()
{
	long long int a1, b1, a2, b2;
 	scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);

	printf("%s + %s = %s\n", Simply(a1, b1).c_str(), Simply(a2, b2).c_str(), Simply(a1 * b2 + a2 * b1, b1 * b2).c_str());
	printf("%s - %s = %s\n", Simply(a1, b1).c_str(), Simply(a2, b2).c_str(), Simply(a1 * b2 - a2 * b1, b1 * b2).c_str());
	printf("%s * %s = %s\n", Simply(a1, b1).c_str(), Simply(a2, b2).c_str(), Simply(a1 * a2, b1 * b2).c_str());
	printf("%s / %s = %s\n", Simply(a1, b1).c_str(), Simply(a2, b2).c_str(), Simply(a1 * b2, b1 * a2).c_str());

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值