给定一个表示分数加减运算的字符串 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 位整数范围内的有效整数。
方法一:模拟 对于两个分数 \dfrac{x_1}{y_1} 和 \dfrac{x_2}{y_2,它们相加的结果为:
\dfrac{x_1 \times y_2 + x_2 \times y_1}{y_1 \times y_2
初始分数的分子为 x} = 0,分母为 y} = 1。我们不断从字符串中获取下一个分数,它的分子为 x}_1,分母为 y}_1,将它加到初始分数上,有:
\begin{cases} \textit{x} = \textit{x} \times \textit{y}_1 + \textit{x}_1 \times \textit{y} \ \textit{y} = \textit{y} \times \textit{y}_1 \end{cases}
最后如果 x} = 0,说明结果为零,直接返回 “0/1”;否则计算分子分母的最大公约数,返回约简后分数的字符串表示。
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution : def fractionAddition (self, expression: str ) -> str : x, y = 0 , 1 i, n = 0 , len (expression) while i < n: x1, sign = 0 , 1 if expression[i] == '-' or expression[i] == '+' : if expression[i] == '-' : sign = -1 i += 1 while i < n and expression[i].isdigit(): x1 = x1 * 10 + int (expression[i]) i += 1 x1 = sign * x1 i += 1 y1 = 0 while i < n and expression[i].isdigit(): y1 = y1 * 10 + int (expression[i]) i += 1 x = x * y1 + x1 * y y *= y1 if x == 0 : return "0/1" g = gcd(abs (x), y) return f"{x // g} /{y // g} "
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution {public : string fractionAddition (string expression) { long long x = 0 , y = 1 ; int index = 0 , n = expression.size (); while (index < n) { long long x1 = 0 , sign = 1 ; if (expression[index] == '-' || expression[index] == '+' ) { sign = expression[index] == '-' ? -1 : 1 ; index++; } while (index < n && isdigit (expression[index])) { x1 = x1 * 10 + expression[index] - '0' ; index++; } x1 = sign * x1; index++; long long y1 = 0 ; while (index < n && isdigit (expression[index])) { y1 = y1 * 10 + expression[index] - '0' ; index++; } x = x * y1 + x1 * y; y *= y1; } if (x == 0 ) { return "0/1" ; } long long g = gcd (abs (x), y); return to_string (x / g) + "/" + to_string (y / g); } };
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public String fractionAddition (String expression) { long x = 0 , y = 1 ; int index = 0 , n = expression.length(); while (index < n) { long x1 = 0 , sign = 1 ; if (expression.charAt(index) == '-' || expression.charAt(index) == '+' ) { sign = expression.charAt(index) == '-' ? -1 : 1 ; index++; } while (index < n && Character.isDigit(expression.charAt(index))) { x1 = x1 * 10 + expression.charAt(index) - '0' ; index++; } x1 = sign * x1; index++; long y1 = 0 ; while (index < n && Character.isDigit(expression.charAt(index))) { y1 = y1 * 10 + expression.charAt(index) - '0' ; index++; } x = x * y1 + x1 * y; y *= y1; } if (x == 0 ) { return "0/1" ; } long g = gcd(Math.abs(x), y); return Long.toString(x / g) + "/" + Long.toString(y / g); } public long gcd (long a, long b) { long remainder = a % b; while (remainder != 0 ) { a = b; b = remainder; remainder = a % b; } return b; } }
[sol1-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public class Solution { public string FractionAddition (string expression ) { long x = 0 , y = 1 ; int index = 0 , n = expression.Length; while (index < n) { long x1 = 0 , sign = 1 ; if (expression[index] == '-' || expression[index] == '+' ) { sign = expression[index] == '-' ? -1 : 1 ; index++; } while (index < n && char .IsDigit(expression[index])) { x1 = x1 * 10 + expression[index] - '0' ; index++; } x1 = sign * x1; index++; long y1 = 0 ; while (index < n && char .IsDigit(expression[index])) { y1 = y1 * 10 + expression[index] - '0' ; index++; } x = x * y1 + x1 * y; y *= y1; } if (x == 0 ) { return "0/1" ; } long g = GCD(Math.Abs(x), y); return (x / g).ToString() + "/" + (y / g).ToString(); } public long GCD (long a, long b ) { long remainder = a % b; while (remainder != 0 ) { a = b; b = remainder; remainder = a % b; } return b; } }
[sol1-C] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #define MAX_STR_LEN 80 long long gcd (long long a, long long b) { long remainder = a % b; while (remainder != 0 ) { a = b; b = remainder; remainder = a % b; } return b; } char * fractionAddition (char * expression) { long long x = 0 , y = 1 ; int index = 0 , n = strlen (expression); while (index < n) { long long x1 = 0 , sign = 1 ; if (expression[index] == '-' || expression[index] == '+' ) { sign = expression[index] == '-' ? -1 : 1 ; index++; } while (index < n && isdigit (expression[index])) { x1 = x1 * 10 + expression[index] - '0' ; index++; } x1 = sign * x1; index++; long long y1 = 0 ; while (index < n && isdigit (expression[index])) { y1 = y1 * 10 + expression[index] - '0' ; index++; } x = x * y1 + x1 * y; y *= y1; } if (x == 0 ) { return "0/1" ; } long long g = gcd(abs (x), y); char *ans = (char *)malloc (sizeof (char ) * MAX_STR_LEN); sprintf (ans, "%d/%d" , x / g, y / g); return ans; }
[sol1-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 func fractionAddition (expression string ) string { x, y := 0 , 1 for i, n := 0 , len (expression); i < n; { x1, sign := 0 , 1 if expression[i] == '-' || expression[i] == '+' { if expression[i] == '-' { sign = -1 } i++ } for i < n && unicode.IsDigit(rune (expression[i])) { x1 = x1*10 + int (expression[i]-'0' ) i++ } x1 = sign * x1 i++ y1 := 0 for i < n && unicode.IsDigit(rune (expression[i])) { y1 = y1*10 + int (expression[i]-'0' ) i++ } x = x*y1 + x1*y y *= y1 } if x == 0 { return "0/1" } g := gcd(abs(x), y) return fmt.Sprintf("%d/%d" , x/g, y/g) } func gcd (a, b int ) int { for a != 0 { a, b = b%a, a } return b } func abs (x int ) int { if x < 0 { return -x } return x }
[sol1-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 var fractionAddition = function (expression ) { let x = 0 , y = 1 ; let index = 0 , n = expression.length ; while (index < n) { let x1 = 0 , sign = 1 ; if (expression[index] === '-' || expression[index] === '+' ) { sign = expression[index] === '-' ? -1 : 1 ; index++; } while (index < n && isDigit (expression[index])) { x1 = x1 * 10 + expression[index].charCodeAt () - '0' .charCodeAt (); index++; } x1 = sign * x1; index++; let y1 = 0 ; while (index < n && isDigit (expression[index])) { y1 = y1 * 10 + expression[index].charCodeAt () - '0' .charCodeAt (); index++; } x = x * y1 + x1 * y; y *= y1; } if (x === 0 ) { return "0/1" ; } const g = gcd (Math .abs (x), y); return Math .floor (x / g) + "/" + Math .floor (y / g); } const gcd = (a, b ) => { let remainder = a % b; while (remainder !== 0 ) { a = b; b = remainder; remainder = a % b; } return b; }; const isDigit = (ch ) => { return parseFloat (ch).toString () === "NaN" ? false : true ; }
复杂度分析