分数
1.分数的表示
可以使用结构体
struct Fraction{ //分数
int up, down; //分子、分母
}a, b;
定义Fraction时遵循三项规则
- 分母为非负数
- 分数为0时,分子为0,分母为1
- 分子分母没有除了1以外的公约数
2.分数的化简
Fraction reduction(Fraction result) {
if(result.down < 0){ //1.分母为负数,令分子和分母都变为相反数
result.down = -result.down;
result.up = -result.up;
}
if(result.up == 0) result.down = 1; //2.分字如果为零,则分母为1;
else{ //如果不为零,则分数取最简形式
int d = gcd(abs(result.down), abs(result.up)); //3.取最大公约数
result.down /= d; //约去最大公约数
result.up /= d;
}
return result;
}
3.分数的四则运算
1.分数的乘法
Fraction add(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.down;
result.up = f1.up * f2.down + f1.down * f2.up;
return reduction(result);
}
2.分数的减法
Fraction minu(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.down;
result.up = f1.up * f2.down - f1.down * f2.up;
return reduction(result);
}
3.分数的乘法
Fraction multi(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.down;
result.up = f1.up * f2.up;
return reduction(result);
}
4.分数的除法
Fraction divide(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.up;
result.up = f1.up * f2.down;
return reduction(result);
}
4.分数的输出
有以下几个注意点:
- 先进行一次reduction()化简
- 如果分母为1,说明分数是整数
- 如果为假分数,可以按带分数的形式输出,整数部分为r.up / r.down,分数部分为abs(r.up)% down, 分母部分为r.down
- 分数的乘法和除法可能会使分子和分母超过int的界限,一般情况下,分子分母应当使用long long型来存储
void showResult(Fraction r){ //输出分数r
r = reduction(r);
if(r.down == 1) {
printf("%lld", r.up); //整数
}else if(abs(r.up) > abs(r.down)){ //假分数
printf("%lld %lld/%lld", r.up / r.down, r.up % r.down, r.down);
}else{ //真分数
printf("%lld/%lld", r.up, r.down);
}
}
例题
分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。
Sample Input 1:
2/3 -4/2
Sample Output 1:
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
Sample Input 2:
5/3 0/6
Sample Output 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 <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
struct Fraction{ //分数
ll up, down; //分子、分母
}a, b;
//欧几里得算法(求最大公约数)
int gcd(ll a, ll b){
if(b == 0) return a;
else return gcd(b, a % b);
}
//分数的表示
//1.使down为非负数
//2.分数为0时,分子为0,分母为1
//3.分子分母没有除1以外的最大公约数
Fraction reduction(Fraction result) {
if(result.down < 0){ //分母为负数,令分子和分母都变为相反数
result.down = -result.down;
result.up = -result.up;
}
if(result.up == 0) result.down = 1; //分字如果为零,则分母为1;
else{ //如果不为零,则分数取最简形式
int d = gcd(abs(result.down), abs(result.up)); //取最大公约数
result.down /= d; //约去最大公约数
result.up /= d;
}
return result;
}
Fraction add(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.down;
result.up = f1.up * f2.down + f1.down * f2.up;
return reduction(result);
}
Fraction minu(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.down;
result.up = f1.up * f2.down - f1.down * f2.up;
return reduction(result);
}
Fraction multi(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.down;
result.up = f1.up * f2.up;
return reduction(result);
}
Fraction divide(Fraction f1, Fraction f2){
Fraction result;
result.down = f1.down * f2.up;
result.up = f1.up * f2.down;
return reduction(result);
}
void showResult(Fraction r){ //输出分数r
r = reduction(r);
if(r.up < 0) printf("(");
if(r.down == 1) {
printf("%lld", r.up); //整数
}else if(abs(r.up) > abs(r.down)){ //假分数
printf("%lld %lld/%lld", r.up / r.down, r.up % r.down, r.down);
}else{ //真分数
printf("%lld/%lld", r.up, r.down);
}
if(r.up < 0) printf(")");
}
int main(){
scanf("%lld/%lld %lld/%lld",&a.up, &a.down, &b.up, &b.down);
//加法
showResult(a);
printf(" + ");
showResult(b);
printf(" = ");
showResult(add(a, b));
printf("\n");
//减法
showResult(a);
printf(" - ");
showResult(b);
printf(" = ");
showResult(minu(a, b));
printf("\n");
//乘法
showResult(a);
printf(" * ");
showResult(b);
printf(" = ");
showResult(multi(a, b));
printf("\n");
//除法
showResult(a);
printf(" / ");
showResult(b);
printf(" = ");
if(b.up == 0 ) printf("Inf");
else showResult(divide(a, b));
return 0;
}