• 数学问题——分数的四则运算


      所谓分数的四则运算是指,给定两个分数的分子和分母,求它们加减乘除的结果。

     

    一、 分数的表示和化简

      1. 分数的表示

      对一个分数来说,最简洁的写法就是写成 假分数 的形式。因此可以使用一个结构体来储存这种只有分子和分母的分数:

    1 // 分数的表示
    2 typedef struct {
    3     int up, down;    // 分子,分母 
    4 } Fraction; 

      于是就可以定义 Fraction 类型的变量来表示分数,或者定义数组来表示一堆分数。其中需要对这种表示制定三项规则:

      • 使 down 为非负。若分数为负,那么令分子 up 为负即可。
      • 如果该分数恰为 0,那么规定其分子为 0,分母为 1。
      • 分子和分母没有除了 1 之外的公约数    

      2. 分数的化简

      分数的化简主要用来使 Fraction 变量满足上述分数表示的三项规则,因此化简步骤也可分成以下三步:

      • 如果分母 down 为负数,那么令分子 up 和分母 down 都变为相反数。
      • 如果分子 up 为 0,那么令分母 down 为 1。
      • 约分:求出分子绝对值与分母绝对值的最大公约数 d,然后令分子分母同时除以 d。    

      代码如下:

     1 // 分数化简
     2 Fraction reduction(Fraction result) {
     3     if(result.down < 0) {    // 分母为负数 
     4         result.up = -result.up;
     5         result.down = -result.down;
     6     }
     7     if(result.up == 0) {    // 分数为 0 
     8         result.down = 1;    
     9     } else {    // 约分 
    10         int d = gcd(abs(result.up), abs(result.down));    // 求最大公约数
    11         result.up /= d;    // 约分
    12         result.down /= d; 
    13     } 
    14     
    15     return result;
    16 } 

    二、 分数的四则运算

      1.  分数的加法

      对两个分数 f1 和 f2 ,其加法计算公式为

        $ result = frac{f1.up*f2.down + f2.up*f1.down}{f1.down*f2.down} $

      代码如下:

    1 // 分数的加法 
    2 Fraction add(Fraction f1, Fraction f2) {
    3     Fraction result;
    4     result.up = f1.up*f2.down + f2.up*f1.down;    // 结果的分子 
    5     result.down = f1.down*f2.down;                 // 结果的分母
    6     return  reduction(result);                    // 化简 
    7 }

      2. 分数的减法

      对两个分数 f1 和 f2,其减法计算公式为

        $ result = frac{f1.up*f2.down - f2.up*f1.down}{f1.down*f2.down} $

      代码如下:

    1 // 分数的减法
    2 Fraction minu(Fraction f1, Fraction f2) {
    3     Fraction result;
    4     result.up = f1.up*f2.down - f2.up*f1.down;    // 结果的分子 
    5     result.down = f1.down*f2.down;                 // 结果的分母
    6     return  reduction(result);                    // 化简 
    7 }

      3. 分数的乘法

      对两个分数 f1 和 f2 ,其乘法计算公式为

        $ result = frac{f1.up*f2.up}{f1.down*f2.down} $

      代码如下:

    1 // 分数的乘法
    2 Fraction multi(Fraction f1, Fraction f2) {
    3     Fraction result;
    4     result.up = f1.up*f2.up;                    // 结果的分子 
    5     result.down = f1.down*f2.down;                 // 结果的分母
    6     return  reduction(result);                    // 化简 
    7 }

      4. 分数的除法

      对两个分数 f1 和 f2 ,其除法计算公式为

        $ result = frac{f1.up*f2.down}{f1.down*f2.up} $

      代码如下:

    1 // 分数的除法
    2 Fraction divide(Fraction f1, Fraction f2) {
    3     Fraction result;
    4     result.up = f1.up*f2.down;                    // 结果的分子 
    5     result.down = f1.down*f2.up;                 // 结果的分母
    6     return  reduction(result);                    // 化简 
    7 }

      分数有额外注意事项。如果读入的除数为 0,那么应当直接特判输出题目要求的输出语句。只有当除数不为 0 时,才能用上面的函数进行计算。

     

    三、 分数的输出

      分数的输出根据题目的要求进行,但是大体上有以下几个注意点:

      • 输出分数前,需要先对其进行化简。
      • 如果分数 r 的分母 down 为 1,直接输出分子,而省略分母的输出。
      • 如果分数 r 的分子 up 的绝对值大于分母 down,此时应按带分数的形式输出,即整数部分为 r.up/r.down ,分子部分为 abs(r.up)%r.down,分母部分为 r.down。
      • 以上均不满足按原样输出即可    

      代码如下:

     1 // 分数的输出 
     2 void showResult(Fraction r) {
     3     r = reduction(r);        // 化简
     4     if(r.down == 1) {        // r 为整数 
     5         printf("%lld
    ", r.up); 
     6     }  else if(abs(r.up) > r.down) {    // r 为假分数 
     7         printf("%d %d/%d
    ", r.up/r.down, abs(r.up)%r.down, r.down); 
     8     } else {
     9         printf("%d/%d
    ", r.up, r.down);
    10     }
    11 }

      为了防止计算时溢出,分子和分母应当使用 long long 型来存储。

    完整代码如下:

     1 /*
     2     分数的四则运算 
     3 */
     4 
     5 #include <stdio.h>
     6 #include <string.h>
     7 #include <math.h>
     8 #include <stdlib.h>
     9 #include <time.h>
    10 
    11 // 分数的表示
    12 typedef struct {
    13     int up, down;    // 分子,分母 
    14 } Fraction; 
    15 
    16 // 欧几里得算法求最大公约数 
    17 int gcd(int a, int b) {
    18     if(b == 0)    return a;
    19     else return gcd(b, a%b);
    20 }
    21 
    22 // 分数化简
    23 Fraction reduction(Fraction result) {
    24     if(result.down < 0) {    // 分母为负数 
    25         result.up = -result.up;
    26         result.down = -result.down;
    27     }
    28     if(result.up == 0) {    // 分数为 0 
    29         result.down = 1;    
    30     } else {    // 约分 
    31         int d = gcd(abs(result.up), abs(result.down));    // 求最大公约数
    32         result.up /= d;    // 约分
    33         result.down /= d; 
    34     } 
    35     
    36     return result;
    37 } 
    38 
    39 // 分数的加法 
    40 Fraction add(Fraction f1, Fraction f2) {
    41     Fraction result;
    42     result.up = f1.up*f2.down + f2.up*f1.down;    // 结果的分子 
    43     result.down = f1.down*f2.down;                 // 结果的分母
    44     return  reduction(result);                    // 化简 
    45 }
    46 
    47 // 分数的减法
    48 Fraction minu(Fraction f1, Fraction f2) {
    49     Fraction result;
    50     result.up = f1.up*f2.down - f2.up*f1.down;    // 结果的分子 
    51     result.down = f1.down*f2.down;                 // 结果的分母
    52     return  reduction(result);                    // 化简 
    53 }
    54 
    55 // 分数的乘法
    56 Fraction multi(Fraction f1, Fraction f2) {
    57     Fraction result;
    58     result.up = f1.up*f2.up;                    // 结果的分子 
    59     result.down = f1.down*f2.down;                 // 结果的分母
    60     return  reduction(result);                    // 化简 
    61 }
    62 
    63 // 分数的除法
    64 Fraction divide(Fraction f1, Fraction f2) {
    65     Fraction result;
    66     result.up = f1.up*f2.down;                    // 结果的分子 
    67     result.down = f1.down*f2.up;                 // 结果的分母
    68     return  reduction(result);                    // 化简 
    69 }
    70 
    71 // 分数的输出 
    72 void showResult(Fraction r) {
    73     r = reduction(r);        // 化简
    74     if(r.down == 1) {        // r 为整数 
    75         printf("%lld
    ", r.up); 
    76     }  else if(abs(r.up) > r.down) {    // r 为假分数 
    77         printf("%d %d/%d
    ", r.up/r.down, abs(r.up)%r.down, r.down); 
    78     } else {
    79         printf("%d/%d
    ", r.up, r.down);
    80     }
    81 }
    82 
    83 int main() {
    84     Fraction f1,f2;
    85     f1.down=2, f1.up=1;
    86     f2.down=6, f2.up=2;
    87     showResult(f1);                // 1/2
    88     showResult(f2);                // 1/3
    89     showResult(add(f1,f2));        // 5/6
    90     showResult(minu(f1,f2));    // 1/6
    91     showResult(multi(f1,f2));    // 1/6
    92     showResult(divide(f1,f2));    // 1 1/2
    93 
    94     return 0;
    95 }
    分数的四则运算
  • 相关阅读:
    《对不队》团队项目软件系统设计改进
    《对不队》团队作业五——项目需求改进
    《对不队》团队作业4—基于原型的团队项目需求调研与分析
    《对不队》第三次作业—团队项目的原型设计与开发
    《对不队团队》第二次作业:学术管理系统开题报告
    《对不队团队》第一次作业:团队亮相
    LINUX命令-shell基础命令
    Python实战-数据结构
    Python实战-函数
    lambda
  • 原文地址:https://www.cnblogs.com/coderJiebao/p/Algorithmofnotes12.html
Copyright © 2020-2023  润新知