本题要求编写程序,计算 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
由于思路不对,一开始将代码写得很复杂(写了200行),却还是有部分用例始终通不过。后来参看了别人的代码,整理了一下思路后重新,很顺利的写出来了。
参看的大神的代码网址为:https://www.cnblogs.com/asheng2016/p/7979386.html
我的代码如下:
#include <iostream> using namespace std; int gcd(long a, long b){ if(b==0){ return a; }else{ gcd(b, a%b); } } void toPrintf(long a, long b){ if(b==0){ printf("Inf"); return ; } if(a==0){ printf("0"); return ; } int flag = 1; //flag为1表示正数 if(a<0) { a = 0 - a; flag *= (-1); } if(b<0){ b = 0 - b; flag *= -1; } long a_b = gcd(a, b); //求最大公约数 a /= a_b; b /= a_b; if(flag<0){ printf("(-"); } if(b==1){ //整数 printf("%ld", a); }else if(a/b==0){ //a/b为0时,不输出 printf("%ld/%ld", a, b); }else{ printf("%ld %ld/%ld", a/b, a%b, b); } if(flag<0){ printf(")"); } } int main(){ long a1, b1, a2, b2; char c[4]={'+', '-', '*', '/'}; scanf("%ld/%ld %ld/%ld", &a1, &b1, &a2, &b2); for(int i=0; i<4; i++){ toPrintf(a1, b1); printf(" %c ", c[i]); toPrintf(a2, b2); printf(" = "); switch(c[i]){ case '+': toPrintf(a1*b2+a2*b1, b1*b2); break; case '-': toPrintf(a1*b2-a2*b1, b1*b2); break; case '*': toPrintf(a1*a2, b1*b2); break; case '/': toPrintf(a1*b2, b1*a2); break; } printf("\n"); } return 0; }
启示一:输入的形式为 2/3 -4/2
对应的接收数据的代码形式为:
scanf("%ld/%ld %ld/%ld", &a1, &b1, &a2, &b2);
于是,很顺利的将数据存入long型变量中了。
启示二:巧妙的将+、-、*、/ 四种操作定义在char数组中,从而用一个for循环很轻松的解决了四种操作。
启示三:求最大公约数时,最好先将a,b化成正数,并用一个变量来记录a/b的正负,从而将(a, b)的四种情况,即:(+,+),(-, +),(+, -),(-, -)化简成了(+,+)这一种情况。