正好学校布置到这一题,也就写出来分享一下我的看法
首先,对于分数,不可避免地就是通分和约分
对于约分:就是寻找最大公约数,除去+-1、0之外的都需要约分操作
最快捷的方法就是辗转相除法,直到取模余0或者用1去取模
举个例子 6 8 :取8%6=2,6%2=0了,得到最大公约数就是 2
另一个例子 13 5 :取13%5=6 ,6%5=1,得到最大公约数就是1
代码如下:
int gys(int x,int y)
{
return y?gys(y,x%y):x; //递归调用gys,返回最大公约数,辗转相除法
}
对于通分:也就是找最小公倍数
在这里设两个数 12 16 :操作就是 用其中一个数 除以 这两个数的最大公约数 再乘 另外一个数,也就是 12/4*16=48,这里找最大公约数就可以调用上一个函数,代码如下:
int gbs(int x,int y)
{
return x/gys(x,y)*y; // 其中一个数除以最大公约数乘上另一个数就是最小公倍数
}
实现对最大公约数的查找之后就可以实现分数的约分了
代码如下:
这里由于要同时返回分子和分母,就偷懒给函数增加一个直接打印输出的功能,详见注释
void yuefen(int fz,int fm) //定义约分函数
{
int s=gys(fz,fm); // 求出最大公约数之后进行约分
fz/=s;
fm/=s;
if(fz<0||fm<0)
{
printf("-%d/%d\n",abs(fz),abs(fm)); // 分数小于 0
}
else if(fz&&fm&&fm!=1)
{
printf("%d/%d\n",abs(fz),abs(fm)); // 正常分数
}
else if(fm==1)
{
printf("%d\n",abs(fz)); // 分母为 1 直接输出整数
}
else
{
printf("0\n"); // 分子为 0 输出 0
}
}
搞定了这几个基本问题之后就可以开始对于+-*/这四则运算开始封装函数了
对于加法和减法,直接通分,最后交给约分函数就可以了
对分子也是同样的先乘再加减
代码如下:
void add(int a,int b,int c,int d) //定义加法函数
{
int u1,u2,v=gbs(b,d),fz1,fm1; // 对最小公倍数通分
u1=v/b*a;
u2=v/d*c;
fz1=u1+u2;
fm1=v;
yuefen(fz1,fm1); // 这几条函数都是得到粗略的结果,最后约分
}
void sub(int a,int b,int c,int d) //定义减法函数
{
int u1,u2,v=gbs(b,d),fz1,fm1;
u1=v/b*a;
u2=v/d*c;
fz1=u1-u2;
fm1=v;
yuefen(fz1,fm1);
}
最后是乘除,相对于加减的通分更加简单,直接调整分子分母的参数即可
代码如下:
void mul(int a,int b,int c,int d) //定义乘法函数
{
int u1,u2;
u1=a*c;
u2=b*d;
yuefen(u1,u2);
}
void div(int a,int b,int c,int d) //定义除法函数
{
int u1,u2;
u1=a*d;
u2=b*c;
yuefen(u1,u2);
}
所有函数都封装完毕了,对于数据流的输入问题,本来我想使用的是sprintf和sscancf,但是学校的编译器好像不太支持这种写法,我就调整为一一对应的scanf输入模式,在判断运算方式的时候也跟上教学进度使用了switch,这里把完整的代码附在最后。
int gys(int x,int y) //定义求最大公约数函数
{
return y?gys(y,x%y):x; //递归调用gys,返回最大公约数,辗转相除法
}
int gbs(int x,int y) //定义求最小公倍数函数
{
return x/gys(x,y)*y; // 其中一个数除以最大公约数乘上另一个数就是最小公倍数
}
void yuefen(int fz,int fm) //定义约分函数
{
int s=gys(fz,fm); // 求出最大公约数之后进行约分
fz/=s;
fm/=s;
if(fz<0||fm<0)
{
printf("-%d/%d\n",abs(fz),abs(fm)); // 分数小于 0
}
else if(fz&&fm&&fm!=1)
{
printf("%d/%d\n",abs(fz),abs(fm)); // 正常分数
}
else if(fm==1)
{
printf("%d\n",abs(fz)); // 分母为 1 直接输出整数
}
else
{
printf("0\n"); // 分子为 0 输出 0
}
}
void add(int a,int b,int c,int d) //定义加法函数
{
int u1,u2,v=gbs(b,d),fz1,fm1; // 对最小公倍数通分
u1=v/b*a;
u2=v/d*c;
fz1=u1+u2;
fm1=v;
yuefen(fz1,fm1); // 这几条函数都是得到粗略的结果,最后约分
}
void mul(int a,int b,int c,int d) //定义乘法函数
{
int u1,u2;
u1=a*c;
u2=b*d;
yuefen(u1,u2);
}
void sub(int a,int b,int c,int d) //定义减法函数
{
int u1,u2,v=gbs(b,d),fz1,fm1;
u1=v/b*a;
u2=v/d*c;
fz1=u1-u2;
fm1=v;
yuefen(fz1,fm1);
}
void div(int a,int b,int c,int d) //定义除法函数
{
int u1,u2;
u1=a*d;
u2=b*c;
yuefen(u1,u2);
}
int main()
{
char op;
char a1,a2;
long a,b,c,d;
scanf("%ld%c%ld %c %ld%c%ld",&a,&a1,&b,&op,&c,&a2,&d);
printf("%ld%c%ld %c %ld%c%ld = ",a,a1,b,op,c,a2,d);
if(a1=='/'&&a2=='/') //判断输入的格式是否正确
{
switch(op) //根据输入的符号选择不同函数的调用
{
case '+':add(a,b,c,d);break; //调用加法函数
case '*':mul(a,b,c,d);break; //调用乘法函数
case '-':sub(a,b,c,d);break; //调用减法函数
case '/':div(a,b,c,d);break; //调用除法函数
}
}
return 0;
}
这篇博客介绍了如何实现分数的约分和通分,通过辗转相除法求最大公约数,进而进行分数的加减乘除运算。博主详细讲解了每个步骤,并提供了C语言的代码实现,包括加法、减法、乘法和除法的函数封装。
2529

被折叠的 条评论
为什么被折叠?



