有理数四则运算(PAT)
1.题目描述
本题要求编写程序,计算2个有理数的和、差、积、商。
2.输入描述:
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。
3.输出描述:
分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。
4.输入例子:
5/3 0/6
5.输出例子:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
6.解题思路:
一、输入时可分为四个整数来分别代表两个分数的分子和分母
二、考虑计算的情况
1、加法、减法和乘法,正常计算
2、除法,当分母为零的时候,输出Inf,(注意:除法计算后可能产生分母为零的情况)
三、 考虑输入分数、计算分数的不同情况,
1、最简正分数1/2
2、最简负分数-1/2
3、假分数3/2,2/2(分子大于等于分母被称为假分数)
4、负假分数-3/2,-3/3
5、分子为0, 0/3
6、分母为负数的情况-2/(-3)、2/(-3),由除法产生的分数
四、考虑分数的化简情况,我们先统一所有分数为正数,在最后输出时在考虑正负,便于化简过程
1、当分子小于分母,为最简分数,无需化简,例如1/2
2、当分子小于分母,非最简分数,需要化简,例如2/4=1/2
3、当分子大于分母,为最简分数,需要化简,例如3/2=1 1/2
4、当分子大于分母,非最简分数,需要化简,例如6/4=1 1/2
五、考虑输出的正负情况,即考虑前面修改负数的情况
源代码中的三目运算,(表达式1)?(表达式2):(表达式3)
如果表达式1为真,则运行表达式2,否则else运算表达式3。
7.源代码:
#include<stdio.h>
int gcd(int x,int y)//取最大公约数
{
return !y? x:gcd(y,x%y);
}
void sp(int x,int y)//化简
{
int m,n;
if(y==0)//分母为零(情况5)
{
printf("Inf");
return;
}
if(y<0)//在除法过程中,分母会产生负数的情况,分子分母互换正负状态(情况6)
{
x*=-1;
y*=-1;
}
m=x<0?-1:1;//将分子均转换为正数处理,因为在后面输出的时候会添加负号。
x*=m,n=gcd(x,y),x/=n,y/=n;//利用最大公约数对分数进行约分为最简式
if(x%y!=0)//分数的余数
{
if(x>y)//分子大于分母,例如5/3、3/2
m>0? printf("%d %d/%d",x/y,x%y,y) : printf("(-%d %d/%d)",x/y,x%y,y);
else
m>0? printf("%d/%d",x,y) : printf("(-%d/%d)",x,y);
}
else//分数的余数为零,例如6/3、2/1
(!x||m>0)? printf("%d",x/y):printf("(-%d)",x/y);
}
int main ()
{
int a1,b1,a2,b2;
scanf("%d/%d %d/%d",&a1,&b1,&a2,&b2);
sp(a1,b1);printf(" + ");sp(a2,b2);printf(" = ");sp(a1*b2+b1*a2,b1*b2);printf("\n");
sp(a1,b1);printf(" - ");sp(a2,b2);printf(" = ");sp(a1*b2-b1*a2,b1*b2);printf("\n");
sp(a1,b1);printf(" * ");sp(a2,b2);printf(" = ");sp(a1*a2,b1*b2);printf("\n");
sp(a1,b1);printf(" / ");sp(a2,b2);printf(" = ");sp(a1*b2,b1*a2);printf("\n");
return 0;
}