【小算法整理】- 分数的运算

博客围绕分数结构体展开,介绍了其表示规则,如使分数非负、特殊值规定及约分等。还给出化简规则,包括处理分母为负、分子为零情况和约分。同时提醒因运算可能超范围,分子分母应用特定类型存储,最后给出具体代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

练习题:PAT. A1081 || PAT. A1088 ||


分数结构体
struct Fraction {
    int up, down; //分子、分母
}; 

结构体的表示规则

  • 1、使down为非负数,如果分数为负,那么令分子up为负即可;
  • 2、如果该分数恰为0,那么规定其分子为0,分母为1
  • 3、分子分母没有除了1以外的公约数;【每次保存完就化简好】
| 化简规则:
  • 1、如果分母down为负,那么令分子和分母都变成相反数;
  • 2、如果分子为 0,那么令分母为1
  • 3、约分:令分子分母同除以两者绝对值的最大公约数
注意点:

由于分数的乘法和除法过程中可能使分子或分母超过int型表示范围,因此一般情况下,分子分母应当使用long long型来存储


具体代码
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;

const int maxn = 110;

struct Fraction {
    int up, down;
}frac[maxn]; 


//最大公约数 
int gcd(int a, int b) {
    if(a < b) swap(a, b);
    if(b == 0) return a;
    else return gcd(b, a % b);
}

//化简整理分数
Fraction reduction(Fraction f) {
    if(f.down < 0) {
        f.up = -f.up;
        f.down = -f.down;
    } 
    if(f.up == 0) f.down = 1;
    else {
        int d = gcd(abs(f.up), abs(f.down)); //若是整数的话,此处就把down化为1了
        f.up /= d;
        f.down /= d;
    }
    return f;
}

//分数加法
Fraction add(Fraction a, Fraction b) {
    a.up = a.up * b.down + b.up * a.down;
    a.down = a.down * b.down;
    return reduction(a);
} 

//分数减法
Fraction minu(Fraction a, Fraction b) {
    a.up = a.up * b.down - b.up * a.down;
    a.down = a.down * b.down;
    return reduction(a);
} 

//分数乘法
Fraction multi(Fraction a, Fraction b) {
    a.up *= b.up;
    a.down *= b.down;
    return reduction(a);
} 

//分数除法
Fraction divide(Fraction a, Fraction b) {
    //判断除数分子(b.up)是否为零,根据题目返回信息 
    a.up *= b.down;
    a.down *= b.up;
    return reduction(a);
} 

//输出分数结果 
void showResult(Fraction a) {
    a = reduction(a); //先化简一下!
    if(a.down == 1) printf("%d", a.up); //整数
    else if(abs(a.up) > a.down) { //假分数
        printf("%d %d/%d", a.up / a.down, abs(a.up) % a.down, a.down);
    } else {                      //真分数
        printf("%d/%d", a.up, a.down);
    }
}

int main() {

    int n;
    Fraction sum, temp;
    sum.up = 0; sum.down = 1;

    scanf("%d", &n); //以求n个分数之和为例
    for(int i = 0; i < n; i++) {
        scanf("%d/%d", &temp.up, &temp.down);
        sum = reduction(add(sum, reduction(temp)));
    }       
    showResult(sum);
    printf("\n");

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值