力扣 592. 分数加减运算

题目

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

示例

输入:“-1/2+1/2”
输出: “0/1”

输入:“-1/2+1/2+1/3”
输出: “1/3”

输入:“1/3-1/2”
输出: “-1/6”

输入:“5/3+1/3”
输出: “2/1”

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fraction-addition-and-subtraction
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法1:模拟

在这里插入图片描述
用欧几里得算法(辗转相除法)
原理是:(a,b)和(b,a mod b)的公约数是一样的。

实现

方法1:python

class Solution:
    def fractionAddition(self, expression: str) -> str:
        res=str() #存每个数据
        zi,mu=list(),list() #分别存分子 分母
        res=expression.replace('-','+-').split('+')
        n,sumzi=len(res),0

        #分子、分母分别存为2个list()
        for num in res:
            if num!='':
                zinum,munum=num.split('/')
                zi.append(zinum) #分子
                mu.append(munum) #分母

        #求分母的最小公倍数
        a=int(mu[0])
        for i in range(1,len(mu)):
            b = int(mu[i])
            var=a*b
            while(b>0):
                temp=a%b
                a,b=b,temp
            a=var/a
        flag=a #最小公倍数,也是分母

        #分子变形后加减的结果
        for i in range(len(zi)):
            sumzi+=int(zi[i])*(flag/int(mu[i]))

        #化简分子分母
        jzi=abs(int(sumzi))
        jmu=flag
        jsu=jzi*jmu
        while(jmu>0):
            temp=jzi%jmu
            jzi,jmu=jmu,temp

        sumzi=int(sumzi)/jzi
        summu=flag/jzi
        return(str(int(sumzi))+'/'+str(int(summu)))

在这里插入图片描述

Java实现
class Solution {
    public String fractionAddition(String expression) {
        int n = expression.length();
        long fz = 0, fm = 1;
        int idx = 0;

        while (idx < n) {
            //提取分子并判断符号
            long fz1 = 0, sign = 1;
            char fh = expression.charAt(idx);
            if (fh == '-' || fh == '+') {
                sign = fh == '-' ? -1 : 1;
                idx++;
            }
            while (idx < n && Character.isDigit(expression.charAt(idx))) {
                fz1 = fz1 * 10 + expression.charAt(idx) - '0';
                idx++;
            }
            fz1 = fz1 * sign;
            idx++;

            //提取分母
            long fm1 = 0;
            while (idx < n && Character.isDigit(expression.charAt(idx))) {
                fm1 = fm1 * 10 + expression.charAt(idx) - '0';
                idx++;
            }
            fz = fz * fm1 + fz1 * fm;
            fm = fm * fm1;
        }

        if (fz == 0) return "0/1";

        //计算分子分母最大公约数
        long g = gcd(Math.abs(fz), fm);
        return Long.toString(fz / g) + "/" + Long.toString(fm / g);
    }

	//辗转相除法
	//原理是:(a,b)和(b,a mod b)的公约数是一样的
    public long gcd(long a, long b) {
        while (b != 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值