分数的表示和化简
分数的表示
用结构体存储只有分子和分母的分数:
struct Fraction
{
int up; //分子
int down; //分母
}
需要对这种表示制定三项规则:
- down必须为非负数,如果分数是负数的情况,那就令分子为负数
- 如果该分数是0,那就令分子为0,分母为1
- 分子和分母没有除1以外的公约数
分数的化简
按照上面的三项规定来化简:
- 如果down为负数,那就让分子和分母变为原来的相反数(即负号往上移)
- 如果分子up等于0,那么令分母为1
- 约分:利用gcd()求出分子绝对值和分母绝对值的最大公约数,然后令分子分母同时除这个公约数
Fraction reduction(Fraction result)
{
if (result.down < 0) // down为负数,让分子和分母变为原来的相反数
{
result.up = -result.up;
result.down = -result.down;
}
if (result.up == 0) //分子up等于0
result.down = 1; //令分母为1
else //约分
{
int d = gcd(abs(result.up), abs(result.down));
result.up /= d;
result.down /= d;
}
return result;
}
分数的四则运算
这就是小学数学题了
分数的加法
同分母分数相加,分母不变,分子相加
异分母分数相加,先通分,再分母不变,分子相加
这里默认一直都是异分母形式:
Fraction add(Fraction f1, Fraction f2)
{
Fraction result;
result.up = f1.up * f2.down + f2.up * f1.down;
result.down = f1.down * f2.down;
return reduction(result);
}
分数的减法
同分母分数相减,分母不变,分子相减
异分母分数相减,先通分,再分母不变,分子相减
Fraction minu(Fraction f1, Fraction f2)
{
Fraction result;
result.up = f1.up * f2.down - f2.up * f1.down;
result.down = f1.down * f2.down;
return reduction(result);
}
分数的乘法
先约分,分子乘分子作为积的分子,分母乘分母作为积的分母
Fraction multi(Fraction f1, Fraction f2)
{
Fraction result;
result.up = f1.up * f2.up;
result.down = f1.down * f2.down;
return reduction(result);
}
分数的除法
除以一个数就等于乘这个数的倒数
Fraction divid(Fraction f1, Fraction f2)
{
Fraction result;
result.up = f1.up * f2.down;
result.down = f1.down * f2.up;
return reduction(result);
}
注意:分数的乘法和除法过程中可能使分子或分母超过int型表示范围,因此一般情况下最好让分子和分母用long long
型存储
分数的输出
分数输出的注意点:
- 输出分数前先化简
- 如果分母为1,说明是整数,直接输出分子(除非题目要求也要输出分母1)
- 如果分子绝对值大于分母,按照带分数的形式输出,整数部分是
up / down
,分子部分是abs(up) % down
,分母部分就是down
- 不满足以上情况说明是真分数,直接按原样输出
void showResult(Fraction r)
{
r = reduction(r);
if (r.down == 1) //分母为1,即整数时
printf("%lld", r.up);
else if (abs(r.up) > r.down) //分子绝对值比分母大,即假分数
printf("%lld %lld/%lld", r.up / r.down, abs(r.up) % r.down, r.down);
else //真分数
printf("%lld/%lld", r.up, r.down);
}