当我第一眼看到这个题的时候,我首先想到用void函数输出不同形式的值,实现不同形式的输出。我今天刷题,把以前没有思路的题重新做了一遍,我觉得作为 初学者,想让小白能够更加容易理解,于是写了一篇文章,大神请放过我这个菜白。
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<stdio.h>
#include<math.h>
int gcd(int x,int y)
{
if(y==0) return x;return gcd(y,x%y);
}
void output(int a,int b)
{
if(a%b==0){
if(a/b<0)printf("(%d)",a/b);else printf("%d",a/b);return;}if(fabs(a)>fabs(b)){
int t=a/b;a=fabs(a)-fabs(t)*fabs(b);b=fabs(b);int z=gcd(a,b);if(t<0){
printf("(%d %d/%d)",t,a/z,b/z);}elseprintf("%d %d/%d",t,a/z,b/z);return;}if(fabs(a)<fabs(b)){
if(a*b<0){
a=fabs(a);b=fabs(b);int t=gcd(a,b);printf("(%d/%d)",-a/t,b/t);}elseprintf("%d/%d",a/gcd(a,b),b/gcd(a,b));return ;}
}
int main(void)
{
int a,b,c,d;scanf("%d/%d %d/%d",&a,&b,&c,&d);for(int i=1;i<=4;i++)
{
output(a,b);if(i==1)printf(" + ");else if(i==2)printf(" - ");else if(i==3)printf(" * ");else printf(" / ");output(c,d);printf(" = ");if(i==1)output(a*d+c*b,b*d);else if(i==2)output(a*d-c*b,b*d);else if(i==3)output(a*c,b*d);else{
if(c==0)printf("Inf");else output(a*d,b*c);}printf("\n");
}
}
我测试的很多数值,但是结果都没有错,然后我有点小小失望吧,然后我去看了一下别的博主的答案,我看到各种各样用着不同语言、不同算法的答案,作为一个小白我看着很心累,于是我就想着写一篇文章分享一下我的简单解法,最终从一位博主中我发现我的问题在于,应该要开long long整型数,因为a*b的值会很大,int是远远不够的。以下是我的改进代码。
#include<stdio.h>
#include<math.h>
long long int gcd(long long int x,long long int y)
{
if(y==0) return x;return gcd(y,x%y);//辗转相除法求最大公因数---为了化简,大家不明白的话我可以单出一个文章帮助大家理解
}
void output(long long int a,long long int b)
{
if(a%b==0){
if(a/b<0)printf("(%d)",a/b);//第一种整除的情况else printf("%d",a/b);return;}if(fabs(a)>fabs(b)){
long long int t=a/b;a=fabs(a)-fabs(t)*fabs(b);//第二种分子大于分母(我写的比较粗糙,作为初学者,我觉得大家可能会有更好的写法b=fabs(b);long long int z=gcd(a,b);if(t<0){
printf("(%d %d/%d)",t,a/z,b/z);}elseprintf("%d %d/%d",t,a/z,b/z);//第三种就是典型的假分数了return;}if(fabs(a)<fabs(b)){
if(a*b<0){
a=fabs(a);b=fabs(b);long long int t=gcd(a,b);printf("(%d/%d)",-a/t,b/t);}elseprintf("%d/%d",a/gcd(a,b),b/gcd(a,b));return ;}
}
int main(void)
{
long long int a,b,c,d;//都开了long long 确实会出现溢出现象scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d);for(long long int i=1;i<=4;i++)
{
output(a,b);if(i==1)printf(" + ");else if(i==2)printf(" - ");else if(i==3)printf(" * ");else printf(" / ");//大家这部分完全可以改进一下output(c,d);printf(" = ");if(i==1)output(a*d+c*b,b*d);else if(i==2)output(a*d-c*b,b*d);else if(i==3)output(a*c,b*d);else{
if(c==0)printf("Inf");else output(a*d,b*c);//有兴趣可以改一下哈}printf("\n");
}
}
当然了,我觉得我的output函数还有在输出的时候可以改进的更好,我的思路比较清晰一点,我作为一个小白写的,希望更多初学者能够看到我的代码,解决自己的疑问。我的if-else if代码可以用更好的swtich代码替换,这里我就不详细多说了。加油各位。
毫无疑问结果是正确的。