题目
给定一个表示分数加减运算表达式的字符串,你需要返回一个字符串形式的计算结果。 这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 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;
}
}