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

这道题真的是很麻烦啊,又要考虑格式,又要考虑超时,需要注意的地方都写在注释里了

#include<iostream>
#include<string>
using namespace std;
long a, b, c, d;
long Numerator, Denominator;
int gcd(long a,long b)//辗转相除法求最大公约数
{
    return b==0?a:gcd(b,a%b);
}
void Calculation(int i)//0-3分别代表加减乘除法
{

	Denominator = b * d;//加减乘的分母都一样,避免重复计算
	if (i == 0)
		Numerator = a * d + b * c;
	else if (i == 1)
		Numerator = a * d - b * c;
	else if (i == 2)
		Numerator = a * c;
	else
	{
		Numerator = a * d;
		Denominator = b * c;
	}
}
string Simplify(long a, long b)
{
	string re;
	if (b == 0 || (a == 0 && b == 0))
		return re = "Inf";
	if (a == 0)
		return re = "0";
	bool flag = false;//判断是否需要加括号
	if ((double)a / b < 0)//避免超出范围
	{
		re += "(-";
		flag = true;
	}
	a = abs(a), b = abs(b);
	if (a >= b)
	{
		re += to_string(a / b);
		a = a % b;
		if (a != 0)
			re += " ";
	}
	if (a != 0)
	{
		int x = gcd(a, b);
		a /= x,b /= x;
		re += to_string(a) + "/" + to_string(b);
	}
	if (flag)
		re += ")";//flag对应在这里
	return re;
}
int main()
{
	char ch;
	cin >> a >> ch >> b >> c >> ch >> d;
	string Operator[4] = { " + "," - "," * "," / " };
	string s1 = Simplify(a, b), s2 = Simplify(c, d);//提前计算出来,避免重复计算
	for (int i = 0; i < 4; i++)
	{
		Calculation(i);
		cout << s1 << Operator[i] << s2 << " = " << Simplify(Numerator, Denominator) << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42582136/article/details/89738818