记录《算法笔记》中“分数的四则运算”相关。
分数的四则运算即可以推广到有理数的四则运算。
分数的表示
分数的最简单表示形式就是写成假分数的形式,用一个结构体来表示分数:
struct Fraction{
int up,down;
};
对这种表示形式定义3项规则:
1. down永远为负数。如果分数为负,则另up为负
2. 如果分数刚好为0,规定up为0,down为1
3. 分子和分母没有除1以外的公约数
分数的化简
分数的化简主要是去满足以上的三项规定,故分数的化简步骤也分为3步:
1. 如果分母down为负数,则另up和down都取各自的相反数
2. 如果分母up为0,则另分母down为1
3. 约分:求出分子绝对值与分母绝对值的最大公约数d,然后分子分母同时除以d
代码如下:
Fraction reduction(Fraction res){
if(res.down < 0){
res.up = -res.up;
res.down = -res.down;
}
if(res.up == 0){
res.down = 1;
}else{
int d = gcd(abs(res.up),abs(res.down)); //求分子分母绝对值的最大公约数
res.up /= d;
res.down /= d;
}
return res;
}
分数的四则运算
加法运算
对于两个分数f1,f2,加法公式为:
res = (f1.up*f2.down + f2.up*f1.down) / f1.down*f2.down
代码如下:
Fraction add(Fraction f1, Fraction f2){
Fraction res;
res.up = f1.up*f2.down + f2.up*f1.down;
res.down = f1.down*f2.down;
return reduction(res); //注意约分
}
减法运算
运算公式:
res = ((f1.up*f2.down - f2.up*f1.down) / f1.down*f2.down)
代码如下:
Fraction minu(Fraction f1, Fraction f2){
Fraction res;
res.up = f1.up*f2.down - f2.up*f1.down;
res.down = f1.down*f2.down;
return reduction(res); //注意约分
}
乘法运算
计算公式如下:
res = (f1.up * f2.up) / (f1.down * f2.down)
代码如下:
Fraction multi(Fraction f1, Fraction f2){
Fraction res;
res.up = f1.up * f2.up;
res.down = f1.down * f2.down;
return reduction(res); //注意约分
}
除法运算
公式如下:
res = (f1.up * f2.down) / (f1.down * f2.up)
代码如下:
Fraction divide(Fraction f1, Fraction f2){
Fraction res;
res.up = f1.up * f2.down;
res.down = f1.down * f2.up;
return reduction(res); //注意约分
}
注意:除法需要注意,除数不能为0。(即f2.up!=0)
分数的输出
输出格式需要根据题目要求进行,但是大体上包括以下几点:
- 化简
- 如果分数r的分母down为1,说明该分数为整数
- 如果分数r的up大于down,则说明r为假分数,可能题目要求输出带分数,即整数部分为r.up/r.down,分子部分为r.up%r.down,分母部分为r.down
- 以上均不满足时说明r是真分数,正常输出
代码如下:
void showResult(Fraction res){
res = reduction(res);
if(r.down == 1){
printf("%lld",r.up);
}else if(abs(r.up) > abs(r.down)){
printf("%d %d/%d", r.up/r.down, r.up%r.down, r.down);
}else{
printf("%d/%d",r.up,r.down);
}
}
注:由于分数的乘法和除法的过程中,可能使分子或分母超过Int的范围,所以一般情况下,分子分母应当使用long long型存储。