[数学] 592. 分数加减运算

149 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

每日刷题 2022.08.05

题目

  • 给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果。 
  • 这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。

示例

  • 示例1
输入: expression = "-1/2+1/2"
输出: "0/1"
  • 示例2
输入: expression = "-1/2+1/2+1/3"
输出: "1/3"
  • 示例3
输入: expression = "1/3-1/2"
输出: "-1/6"

提示

  • 输入和输出字符串只包含 '0' 到 '9' 的数字,以及 '/', '+' 和 '-'。 
  • 输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
  • 输入只包含合法的最简分数,每个分数的分子与分母的范围是  [1,10]。 如果分母是1,意味着这个分数实际上是一个整数。
  • 输入的分数个数范围是 [1,10]。
  • 最终结果的分子与分母保证是 32 位整数范围内的有效整数。

解题思路

  • 第一步先把字符划分成一个个分数,可以通过"+"或者"-"作为分隔遍历
  • 在找每一个分数的同事,可以把每个分数的分子和分母找出来,通过"/"分隔
  • 划分分数时,"+"或者"-"可以看成分子的一部分,这样每个分数都是+a/b或者-a/b的形式,更容易计算
  • 最后对每一组分子和分母进行累加,累加时可以先直接相乘,然后约分

AC代码

/**
 * @param {string} e
 * @return {string}
 */
var fractionAddition = function(e) {
  // 所以这道题还是比较简单的,可以直接用分割函数split()
  // 因为如果是直接的添加+号在前面,那么-1/2+-2/3
  // 好像又不会存在问题
  // 最大公因数
  function gcd(a, b){  // 一般要求a>=0, b>0。若a=b=0,代码也正确,返回0
    return b != 0 ? gcd(b, a%b) : a;
  }
  // 最小公倍数
  function lcm(a, b){ 
    return a / gcd(a, b) * b;
  }
  // 替换掉所有的减号
  let ex = e.replaceAll('-', '+-');
  // console.log(ex)
  // 将每一个分数独立出来,再对每一个分数进行单独的计算
  let es = ex.split('+');
  // console.log(es)
  let n = es.length, ans = '', i = 0;
  // console.log('len:::', n)
  while(i < n) {
    if(es[i] === '') {
      i++;
      continue;
    }
    // console.log('start::', es[i], i)
    // 这样就可以获得前面一部分 和 后面一部分的数值
    // 其实也不需要找最小公倍数,直接将两个分数相乘就可以了
    if(ans === '') {
      // 表示前面还没有计算过,就可以直接赋值
      ans = es[i];
    } else {
      // 否则的话就需要计算下面的结果并储存起来
      let cur = es[i].split('/'), cura = Number(cur[0]), curb = Number(cur[1]);
      // console.log('cur::', cur)
      // 计算过就需要拿ans中的数值和其进行计算
      let yuan = ans.split('/'), yuanA = Number(yuan[0]), yuanB = Number(yuan[1]);
      let mu = curb * yuanB, zi = yuanA * curb + cura * yuanB;
      ans = zi + '/' + mu;
      // console.log('ans:::', ans)
    }
    i++;
  }
  // 最终得到的结果ans,还需要化简
  // 需要除去最大公因数
  let res = ans.split('/');
  // console.log(res)
  let m = gcd(Number(res[0]), Number(res[1]));
  // console.log(m)
  m = Math.abs(m);
  return res[0] / m + '/' + res[1] / m;
};