题目描述

这是 LeetCode 上的 592. 分数加减运算 ,难度为 中等

Tag : 「表达式计算」、「模拟」

给定一个表示分数加减运算的字符串 expression,你需要返回一个字符串形式的计算结果。

这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 ,你需要将它转换成分数形式,其分母为 。所以在上述例子中,  应该被转换为 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' 的数字,以及 '/', '+' 和 '-'
  • 输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
  • 输入只包含合法的最简分数,每个分数的分子与分母的范围是  。 如果分母是 ,意味着这个分数实际上是一个整数。
  • 输入的分数个数范围是 。
  • 最终结果的分子与分母保证是 位整数范围内的有效整数。

表达式计算

为了方便,令 expressions

由于给定的表达式中只有 +-,因此无须考虑优先级问题,直接从前往后计算即可。

使用变量 ans 代指计算过程中的结果,从前往后处理表达式 s,每次以 ±分子/分母 的形式取出当前操作数(若为表达式的首个操作数,且为正数时,需要手动补一个 +)。

假设当前取出的操作数为 num,根据 ans 的情况进行运算:

  • ans 为空串,说明 num 是首个操作数,直接将 num 赋值给 ans 即可
  • ans 不为空串,此时计算 numans 的计算结果赋值给 ans

考虑实现一个计算函数 String calc(String a, String b) 计算两个操作 ab 的结果,其中入参 ab 以及返回值均满足 ±分子/分母 形式。

首先通过读取 ab 的首个字符,得到两操作数的正负情况。若为一正一负,通过交换的形式,确保 a 为正数,b 为负数。

然后通过 parse 方法拆解出字符串操作数的分子和分母,parse 使用指针扫描的方式实现即可,以数组形式将结果返回(第 位为分子数值,第 位分母数值)。

假设操作数 a 对应的值为 ,操作数的值为 ,先将其转换为 和 ,进行运算后,再通过求最大公约数 gcd 的方式进行化简。

Java 代码:

class Solution {    public String fractionAddition(String s) {        int n = s.length();        char[] cs = s.toCharArray();        String ans = "";        for (int i = 0; i < n; ) {            int j = i + 1;            while (j < n && cs[j] != '+' && cs[j] != '-') j++;            String num = s.substring(i, j);            if (cs[i] != '+' && cs[i] != '-') num = "+" + num;            if (!ans.equals("")) ans = calc(num, ans);            else ans = num;            i = j;        }        return ans.charAt(0) == '+' ? ans.substring(1) : ans;    }    String calc(String a, String b) {        boolean fa = a.charAt(0) == '+', fb = b.charAt(0) == '+';        if (!fa && fb) return calc(b, a);        long[] p = parse(a), q = parse(b);        long p1 = p[0] * q[1], q1 = q[0] * p[1];        if (fa && fb) {            long r1 = p1 + q1, r2 = p[1] * q[1], c = gcd(r1, r2);            return "+" + (r1 / c) + "/" + (r2 / c);        } else if (!fa && !fb) {            long r1 = p1 + q1, r2 = p[1] * q[1], c = gcd(r1, r2);            return "-" + (r1 / c) + "/" + (r2 / c);        } else {            long r1 = p1 - q1, r2 = p[1] * q[1], c = gcd(Math.abs(r1), r2);            String ans = (r1 / c) + "/" + (r2 / c);            if (p1 >= q1) ans = "+" + ans;            return ans;        }    }    long[] parse(String s) {        int n = s.length(), idx = 1;        while (idx < n && s.charAt(idx) != '/') idx++;        long a = Long.parseLong(s.substring(1, idx)), b = Long.parseLong(s.substring(idx + 1));        return new long[]{a, b};    }    long gcd(long a, long b) {        return b == 0 ? a : gcd(b, a % b);    }}

TypeScript 代码:

function fractionAddition(s: string): string {    const n = s.length    let ans = ""    for (let i = 0; i < n; ) {        let j = i + 1        while (j < n && s[j] != '+' && s[j] != '-') j++        let num = s.substring(i, j)        if (s[i] != '+' && s[i] != '-') num = "+" + num        if (ans != "") ans = calc(num, ans)        else ans = num        i = j    }    return ans[0] == "+" ? ans.substring(1) : ans};function calc(a: string, b: string): string {    const fa = a[0] == "+", fb = b[0] == "+"    if (!fa && fb) return calc(b, a)    const p = parse(a), q = parse(b)    const p1 = p[0] * q[1], q1 = q[0] * p[1]    if (fa && fb) {        const r1 = p1 + q1, r2 = p[1] * q[1], c = gcd(r1, r2)        return "+" + (r1 / c) + "/" + (r2 / c)    } else if (!fa && !fb) {        const r1 = p1 + q1, r2 = p[1] * q[1], c = gcd(r1, r2)        return "-" + (r1 / c) + "/" + (r2 / c)    } else {        const r1 = p1 - q1, r2 = p[1] * q[1], c = gcd(Math.abs(r1), r2)        let ans = (r1 / c) + "/" + (r2 / c)        if (p1 > q1) ans = "+" + ans        return ans    }}function parse(s: string): number[] {    let n = s.length, idx = 1    while (idx < n && s[idx] != "/") idx++    const a = Number(s.substring(1, idx)), b = Number(s.substring(idx + 1))    return [a, b]}function gcd(a: number, b: number): number {    return b == 0 ? a : gcd(b, a % b)}
  • 时间复杂度:
  • 空间复杂度:

加餐 & 加练

加餐一道更贴合笔试面试的「表达式计算」问题 : 双栈 : 表达式计算问题的通用解法

592. 分数加减运算 : 表达式计算入门题相关推荐

  1. Leetcode 592. 分数加减运算 C++

    Leetcode 592. 分数加减运算 题目 给定一个表示分数加减运算表达式的字符串,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即最简分数. 如果最终结果是一个整数,例如 ...

  2. 592.分数加减运算 纯纯的数学题,Python 7行代码+详细思路分享!

    592.分数加减运算 https://leetcode.cn/problems/fraction-addition-and-subtraction/solution/by-qingfengpython ...

  3. LeetCode 592. 分数加减运算(字符串+最大公约数)

    1. 题目 给定一个表示分数加减运算表达式的字符串,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即最简分数. 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母 ...

  4. 图解LeetCode——592. 分数加减运算(难度:中等)

    一.题目 给定一个表示分数加减运算的字符串 expression,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即:最简分数. 如果最终结果是一个整数,例如 2,你需要将它转换成 ...

  5. 【leetcode】592.分数加减运算(python)

    目录 一.题目描述 二.解题思路 2.1 查找 '/' 所在位置(第一思路) 2.2 利用python中分数表达Fraction函数 2.2.1 Fraction函数介绍 2.2.2 解题 2.3 类 ...

  6. leetcode 592. Fraction Addition and Subtraction | 592. 分数加减运算(最大公因数gcd,最小公倍数lcm)

    题目 https://leetcode.com/problems/fraction-addition-and-subtraction/ 题解 这题既简单又麻烦,一道 hard 的 easy 题,被划分 ...

  7. JAVA程序设计:分数加减运算(LeetCode:592)

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

  8. LeetCode 0592. 分数加减运算:手把手分步のC++讲解

    [LetMeFly]592.分数加减运算:手把手分步のC++讲解 力扣题目链接:https://leetcode.cn/problems/fraction-addition-and-subtracti ...

  9. leetcode_592. 分数加减运算

    问题描述: 给定一个表示分数加减运算表达式的字符串,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即最简分数. 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母 ...

  10. 【数据结构与算法】之深入解析“分数加减运算”的求解思路与算法示例

    一.题目要求 给定一个表示分数加减运算的字符串 expression,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即最简分数. 如果最终结果是一个整数,例如 2,你需要将它转换 ...

最新文章

  1. 软件工程心理学之---让客户知错,但不能向你发怒
  2. AOF-Redis设计与实现
  3. redhat linux下安装oracle10g rac,RedHat 5.5下安装Oracle 10g+RAC
  4. 创建可调试,热加载的TypeScript+Koa工程
  5. ssl提高组国庆模拟赛【2018.10.5】
  6. DCT(离散余弦变换(DiscreteCosineTransform))
  7. Gentle中的数据表实体类相关自定义属性的设置和获得
  8. android布局新建联系人,Android中设置搜素联系人的布局
  9. Java 启动参数大全
  10. Android检测wifi信号强度,检测网络是否通畅
  11. php实现秒数倒计时,jQuery网页倒计时代码 显示天、小时、分钟与秒数
  12. pythonshell窗口是什么_使用IDLE的Python shell窗口实例详解
  13. 安卓权限工具类(二)
  14. 你愿意做高学历却抑郁的人,还是低学历开心的人?(持续更新中)
  15. 趣味数学--贷款计算
  16. 第1章 蓝牙降噪耳机简述
  17. 我逼走创业合伙人,白干七年净身出户,我是跪着前行的CEO
  18. java中6与3等于几_Java(六)
  19. 笔趣阁小说站的爬虫小程序
  20. [渝粤教育] 广东-国家-开放大学 21秋期末考试中国法律史10212k1

热门文章

  1. 信息安全技术--轮转机密码
  2. 在Virtualbox虚拟机中安装MSDOS(简易教程)
  3. 如何快速删除某几页的页眉页脚
  4. 【MTK AF】Acce/Gyro/PD/Laser Driver Check
  5. 洛谷p3376 网络流最大流模板题
  6. 公开信息查询的一些方法,查征信,查婚姻状况,查询公开个人信息
  7. Java 开通会员增加会员天数(LocalDateTime)
  8. 微信二维码扫码登录思路
  9. 2020辽宁国家公务员考试申论模拟题:过度医疗
  10. 超详细wordPress主题制作教程