分数问题,一些小细节的处理特别麻烦,我这里采用的是别人整理好的系统化的方法来进行处理,下面讲解一下思路:
- 这里的分数同一采用假分数的形式来处理,并且规定分母都为正,即如果分母为负数,上下同时取反,数0的写法为分子为0,分母为1
- 化简时,求出分子分母的最大公约数(PS:这里规定求解时都转化成正数,有兴趣的可以百度一下负数的gcd就明白了),然后同时除以最大公约数即可
- 关于输出最后的结果,有下列三种情况:
- 分母为1,表示结果为整数,输出分子即可
- 分子大于分母,转为带分数的形式,注意这里符号和整数部分在一起,然后输出分子取模分母的结果(关于负数的取模运算,有兴趣的百度一下,蛮有意思的,计算机会自动转成绝对值运算,然后符号跟左边的数一致)
- 最后一种情况就是正常的分数,直接输出即可
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct frac{
int up,down;
};
int gcd(int a,int b)//最大公约数不考虑负数
{
if(b==0)return a;
else return gcd(b,a%b);
}
frac simplify(frac a)//保证分母大于0,符号看分子
{
//分母为负数
if(a.down<0){
a.up*=-1;
a.down*=-1;
}
//分子为0
if(a.up==0)a.down=1;
else
{
int t=gcd(abs(a.up),abs(a.down));
a.up/=t;
a.down/=t;
}
return a;
}
frac add(frac a,frac b)
{
frac result;
result.down=a.down*b.down;
result.up=a.up*b.down+a.down*b.up;
return simplify(result);
}
int main()
{
int n;
cin>>n;
frac sum,temp;
sum.up=0;sum.down=1;
for(int i=0;i<n;i++)
{
scanf("%d/%d",&temp.up,&temp.down);
sum=add(sum,temp);
}
if(sum.down==1)cout<<sum.up/sum.down;
else if(abs(sum.up)<sum.down)
printf("%d/%d",sum.up,sum.down);
else
{
printf("%d %d/%d",sum.up/sum.down,abs(sum.up)%sum.down,sum.down);
}
}