题目描述
计算机中采用浮点数表示所有实数,但这意味着精度丢失。例如无法精确表示“1/3”。
NowCoder最近要处理很多金融问题,这些账目不允许出现精度丢失,因为差之毫厘谬之千里。你能帮他实现一套分数的计算器吗?
输入描述:
输入包含多组数据。
每组数据一行,包含两个分数和一个运算符,中间用空格隔开。
其中分子与分母均为不大于30的正整数。
输出描述:
对应每一组数据,输出两个分数的计算结果。
要求输出最简分数,即分子与分母互质。
输入例子:
1/3 2/3 +
1/5 1/4 -
1/2 1/3 *
2/3 4/3 /
输出例子:
1/1
-1/20
1/6
1/2
本题的关键是最大公因数
、最小公倍数
的求解。
两数的最大公因数
求解常用辗转相除法
,比如a,b两数(假设a >= b)
while (a % b != 0) {
b’ 赋值为 a / b 余数 (即 a % b)
a‘ 赋值为 b
a = a’, b = b'
}
两数的最小公倍数
求解有个数学规律
a、b最小公倍数 = a * b / (a、b最大公因数)
#include <iostream>
#include <math.h>
using namespace std;
// 求number1、number2的最大公因数
int gcd(int number1, int number2) {
int tempNum = 0;
//保持number1不小于number2
if (number1 < number2) {
//借助tempNum,将number1、number2进行交换
tempNum = number1;
number1 = number2;
number2 = tempNum;
}
//判断number1是否能整除number2
while (number1 % number2 != 0) {
//ba余数赋给tempNum
tempNum = number1 % number2;
//把number2赋给number1,tempNum赋给number2
//由于进行求余时,number2是除数,tempNum是余数,所以number2 > tempNum
//赋值操作后继续维持了 number1 > number2
number1 = number2;
number2 = tempNum;
}
return number2;
}
// 求number1、number2的最小公倍数
int lcm(int number1, int number2) {
//最小公倍数 = 两数相乘 / 最大公因数
return number1 * number2 / gcd(number1, number2);
}
int main(int argc, const char * argv[]) {
char op = '\0';
// 分数numerator1/denominator1,参数1 分数numerator2/denominator2 参数2
int numerator1 = 1, denominator1 = 1, numerator2 = 1, denominator2 = 1;
//scanf返回值为正确输入数据的变量个数,当一个变量都没有成功获取数据时,此时返回-1
while (scanf("%d/%d %d/%d %c", &numerator1, &denominator1, &numerator2, &denominator2, &op) != - 1) {
//记录结果是否为负数
bool flag = false;
//分数numerator3/denominator3,结果
int numerator3 = 0, denominator3 = 0;
if (op == '+') {
//处理分数加法,先分母同分,然后分子与分母交叉相乘
denominator3 = denominator1 * denominator2;
numerator3 = numerator1 * denominator2 + numerator2 * denominator1;
}
if (op == '-') {
//处理分数减法,先分母同分,然后分子与分母交叉相乘
denominator3 = denominator1 * denominator2;
numerator3 = numerator1 * denominator2 - numerator2 * denominator1;
if (numerator3 < 0) {
//这里单独记录负号,是因为求解公因数、公倍数是不能有负数
flag = true;
numerator3 = -numerator3;
}
}
if (op == '*') {
//处理分数乘法,分母相乘,分子相乘
denominator3 = denominator1 * denominator2;
numerator3 = numerator1 * numerator2;
}
if (op == '/') {
//处理分数除法,分母1 分子2 相乘作分母,分子1 分母2 相乘 作分子
denominator3 = denominator1 * numerator2;
numerator3 = numerator1 * denominator2;
}
if (numerator3 == 0) {
printf("0\n");
} else {
//分子、分母分别除最大公因数进行约分
int tempNum = gcd(numerator3, denominator3);
numerator3 /= tempNum;
denominator3 /= tempNum;
//如果是减法可能产生负数,因此需要输出负号
printf((flag ? "-%d/%d\n" : "%d/%d\n"), numerator3, denominator3);
}
}
return 0;
}