1088. Rational Arithmetic (20)

本文介绍了一种利用欧几里德算法简化分数并进行分数加减乘除运算的方法,通过字符串到数字的转换处理复杂输入,并提供完整的代码实现。

1.注意在数字和string转化过程中,需要考虑数字不是只有一位的,如300转为“300”,一开始卡在里这里,

测试用例:

24/8 100/10
24/11 300/11

2.该题用到了欧几里德算法求最小公约数gcd(a,b)

算法如下:

//欧几里德算法求最大公约数gcd,其中a>b
long long gcd(long long a, long long b)
{
	return b == 0 ? a : gcd(b, a%b);
}


AC代码如下:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;

/*
24/8 100/10
24/11 300/11
*/


//欧几里德算法求最大公约数gcd
long long gcd(long long a, long long b)
{
	return b == 0 ? a : gcd(b, a%b);
}
void str2num(string str, long long&top, long long&bot, int&sign)
{
	bool first = true;
	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] == '-')
			sign = -1;
		else if (str[i] != '/'&&first)
			top = top * 10 + str[i] - '0';
		else if (str[i] == '/')
			first = false;
		else if (str[i] != '/'&&!first)
			bot = bot * 10 + str[i] - '0';
	}
}
string i2s(long long a)
{
	string ans = "";
	if (a == 0) return "0";
	else
	{
		while (a != 0)
		{
			char c = a % 10 + '0';
			ans = c + ans;
			a /= 10;
		}
	}
	return ans;
}
string int2Str(long long top, long long bot, bool sign)
{
	long long tmpGCD = gcd(top, bot);
	top /= tmpGCD;
	bot /= tmpGCD;
	long long tmpInt = top / bot;
	long long tmpRat = top%bot;
	string ans = "";
	if (tmpInt != 0)
	{
		ans = i2s(tmpInt);
	}
	if (tmpRat == 0 && ans.size() != 0)
		;
	else if (tmpRat == 0 && ans.size() == 0)
	{
		return "0";
	}
	else if (tmpRat != 0 && ans.size() != 0)
	{//整数和分数同时存在
		ans += " "+i2s(tmpRat) + "/" + i2s(bot);
	}
	else if (tmpRat != 0 && ans.size() == 0)
	{//仅存在分数
		ans += i2s(tmpRat) + "/" + i2s(bot);
	}
	if (!sign)
		ans = "(-" + ans + ")";
	return ans;
}
int main(void)
{
	string a, b;
	cin >> a >> b;
	long long aTop = 0, aBot = 0, bTop = 0, bBot = 0;
	int aSign = 1;
	int bSign = 1;
	str2num(a, aTop, aBot, aSign);
	str2num(b, bTop, bBot, bSign);
	string aAns;
	string bAns;
	if (aTop != 0)
	{
		int aGCD = gcd(aTop, aBot);
		aTop /= aGCD;
		aBot /= aGCD;
		aAns = int2Str(aTop, aBot, aSign == 1);
	}
	else aAns = "0";
	if (aTop != 0)
	{
		int bGCD = gcd(bTop, bBot);
		bTop /= bGCD;
		bBot /= bGCD;
		bAns = int2Str(bTop, bBot, bSign == 1);
	}
	else 
		bAns = "0";

	//加法:
	long long addBot = aBot*bBot;
	long long addTop = aSign*aTop*bBot + bSign*bTop*aBot;
	bool addSign = (addTop >= 0 ? true : false);
	addTop = labs(addTop);
	long long addInt = addTop / addBot;
	string addAns = int2Str(addTop, addBot, addSign);
	cout << aAns << " + " << bAns << " = " << addAns << endl;

	//减法:
	long long diffBot = aBot*bBot;
	long long diffTop = aSign*aTop*bBot - bSign*bTop*aBot;
	bool diffSign = (diffTop >= 0 ? true : false);
	diffTop = labs(diffTop);
	long long diffInt = diffTop / diffBot;
	string diffAns = int2Str(diffTop, diffBot, diffSign);
	cout << aAns << " - " << bAns << " = " << diffAns << endl;

	//乘法
	long long proBot = aBot*bBot;
	long long proTop = aSign*bSign*aTop*bTop;
	bool proSign = (proTop >= 0 ? true : false);
	proTop = labs(proTop);
	long long proInt = proTop / proBot;
	string proAns = int2Str(proTop, proBot, proSign);
	cout << aAns << " * " << bAns << " = " << proAns << endl;


	//除法
	long long quoBot = aBot*bTop;
	long long quoTop = aSign*bSign*aTop*bBot;
	string quoAns;
	if (quoBot != 0)
	{
		bool quoSign = (quoTop >= 0 ? true : false);
		quoTop = labs(quoTop);
		long long quoInt = quoTop / quoBot;
		quoAns = int2Str(quoTop, quoBot, quoSign);
	}
	else
		quoAns = "Inf";
	cout << aAns << " / " << bAns << " = " << quoAns << endl;

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值