1. 问题描述:
给定一个表示分数加减运算表达式的字符串,你需要返回一个字符串形式的计算结果。 这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。
示例 1:
输入:"-1/2+1/2"
输出: "0/1"
示例 2:
输入:"-1/2+1/2+1/3"
输出: "1/3"
示例 3:
输入:"1/3-1/2"
输出: "-1/6"
示例 4:
输入:"5/3+1/3"
输出: "2/1"
说明:
输入和输出字符串只包含 '0' 到 '9' 的数字,以及 '/', '+' 和 '-'。
输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
输入只包含合法的最简分数,每个分数的分子与分母的范围是 [1,10]。 如果分母是1,意味着这个分数实际上是一个整数。
输入的分数个数范围是 [1,10]。
最终结果的分子与分母保证是 32 位整数范围内的有效整数。
2. 思路分析:
① 一个最简单的想法是依次计算相邻两个分数的结果,所以首先我们就需要获取分数中的数字,可以使用正则表达式分割字符串获取对应分数的分子与分母,因为使用的是python语言,所以可以使用python中的re模块,使用正则表达式的方法进行分割,首先我们可以使用"+"或"-"分割,这样可以获取所有分数对应的列表,然后遍历这个列表,然后再对当前遍历的字符串使用正则表达式进行分割,这里可以使用"/"进行分割,这样就可以得到当前分数对应的分子与分母,为了方便计算我们可以在一开始的时候设置上一个分子与分母的值分别为0,1,这样可以避免边界上的问题,然后就可以依次计算相邻两个分数相加减的结果了
② 因为需要得到最简的分数,计算分数相加减的时候使用下面的方法进行计算得到的分子与分母肯定是最简的
3. 代码如下:
import re
class Solution:
# 求解最大公约数
def gcd(self, a: int, b: int):
while b != 0:
t = b
b = a % b
a = t
return a
def fractionAddition(self, expression: str) -> str:
signs = list()
# 处理第一个符号这样后面可以设置上一个的分子与分母进行相邻两个分数的计算
if expression[0] != "-": signs.append("+")
# 预处理这样可以得到分数计算的所有符号
for i in range(len(expression)):
if expression[i] == "+" or expression[i] == "-": signs.append(expression[i])
i = 0
if expression[0] == "-": i += 1
# 这里使用到python分割字符串的方法
# split方法第一个参数为正则表达式, 第二个为需要分割的字符串
s_split = re.split(r'[+|-]', expression)
pre_fenzi, pre_fenmu = 0, 1
i = 0
for s in s_split:
if s == "": continue
s1 = re.split("/", s)
cur_fenzi = int(s1[0])
cur_fenmu = int(s1[1])
# print(cur_fenzi, cur_fenmu)
g = self.gcd(abs(cur_fenmu), abs(pre_fenmu))
if signs[i] == "+":
pre_fenzi = pre_fenzi * cur_fenmu // g + pre_fenmu * cur_fenzi // g
else:
pre_fenzi = pre_fenzi * cur_fenmu // g - pre_fenmu * cur_fenzi // g
i += 1
pre_fenmu = cur_fenmu * pre_fenmu // g
g = abs(self.gcd(pre_fenzi, pre_fenmu))
pre_fenzi //= g
pre_fenmu //= g
return str(pre_fenzi) + "/" + str(pre_fenmu)