✨ Add latex generating in steps
This commit is contained in:
		| @@ -56,13 +56,12 @@ class SolverService { | ||||
|     final steps = <CalculationStep>[]; | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第一步:表达式求值", | ||||
|         explanation: "这是一个标准的数学表达式,我们将直接计算其结果。", | ||||
|         title: '第一步:表达式求值', | ||||
|         explanation: '这是一个标准的数学表达式,我们将直接计算其结果。', | ||||
|         formula: input, | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     // **FIXED**: Correct usage of the math_expressions library | ||||
|     Parser p = Parser(); | ||||
|     Expression exp = p.parse(input); | ||||
|     ContextModel cm = ContextModel(); | ||||
| @@ -75,134 +74,118 @@ class SolverService { | ||||
|   CalculationResult _solveLinearEquation(String input) { | ||||
|     final steps = <CalculationStep>[]; | ||||
|     steps.add( | ||||
|       CalculationStep(title: "原方程", explanation: "这是一元一次方程。", formula: input), | ||||
|       CalculationStep( | ||||
|         title: '原方程', | ||||
|         explanation: '这是一元一次方程。', | ||||
|         formula: '\$\$$input\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     // 解析方程: ax+b=cx+d | ||||
|     final parts = _parseLinearEquation(input); | ||||
|     final a = parts.a, b = parts.b, c = parts.c, d = parts.d; | ||||
|  | ||||
|     // 移项合并 | ||||
|     final newA = a - c; | ||||
|     final newD = d - b; | ||||
|  | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第一步:移项", | ||||
|         explanation: "将所有含 x 的项移到等式左边,常数项移到右边。", | ||||
|         title: '第一步:移项', | ||||
|         explanation: '将所有含 x 的项移到等式左边,常数项移到右边。', | ||||
|         formula: | ||||
|             "${a}x ${c >= 0 ? '-' : '+'} ${c.abs()}x = $d ${b >= 0 ? '-' : '+'} ${b.abs()}", | ||||
|             '\$\$${a}x ${c >= 0 ? '-' : '+'} ${c.abs()}x = $d ${b >= 0 ? '-' : '+'} ${b.abs()}\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第二步:合并同类项", | ||||
|         explanation: "合并等式两边的项。", | ||||
|         formula: "${newA}x = $newD", | ||||
|         title: '第二步:合并同类项', | ||||
|         explanation: '合并等式两边的项。', | ||||
|         formula: '\$\$${newA}x = $newD\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     // 求解x | ||||
|     if (newA == 0) { | ||||
|       if (newD == 0) { | ||||
|         return CalculationResult(steps: steps, finalAnswer: "有无穷多解"); | ||||
|       } else { | ||||
|         return CalculationResult(steps: steps, finalAnswer: "无解"); | ||||
|       } | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
|         finalAnswer: newD == 0 ? '有无穷多解' : '无解', | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     final x = newD / newA; | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第三步:求解 x", | ||||
|         explanation: "两边同时除以 x 的系数 ($newA)。", | ||||
|         formula: "x = $newD / $newA", | ||||
|         title: '第三步:求解 x', | ||||
|         explanation: '两边同时除以 x 的系数 ($newA)。', | ||||
|         formula: '\$\$x = \frac{$newD}{$newA}\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     return CalculationResult(steps: steps, finalAnswer: "x = $x"); | ||||
|     return CalculationResult(steps: steps, finalAnswer: '\$\$x = $x\$\$'); | ||||
|   } | ||||
|  | ||||
|   /// 3. 求解一元二次方程 (升级版) | ||||
|   CalculationResult _solveQuadraticEquation(String input) { | ||||
|     final steps = <CalculationStep>[]; | ||||
|  | ||||
|     // 整理成 ax^2+bx+c=0 的形式并提取系数 | ||||
|     final eqParts = input.split('='); | ||||
|     if (eqParts.length != 2) throw Exception("方程格式错误,应包含一个 '='。"); | ||||
|  | ||||
|     final leftCoeffs = _parsePolynomial(eqParts[0]); | ||||
|     final rightCoeffs = _parsePolynomial(eqParts[1]); | ||||
|  | ||||
|     // 移项合并 | ||||
|     final a = (leftCoeffs[2] ?? 0) - (rightCoeffs[2] ?? 0); | ||||
|     final b = (leftCoeffs[1] ?? 0) - (rightCoeffs[1] ?? 0); | ||||
|     final c = (leftCoeffs[0] ?? 0) - (rightCoeffs[0] ?? 0); | ||||
|  | ||||
|     if (a == 0) { | ||||
|       // 如果 a=0, 这实际上是一个一元一次方程 | ||||
|       return _solveLinearEquation("${b}x+${c}=0"); | ||||
|       return _solveLinearEquation('${b}x+$c=0'); | ||||
|     } | ||||
|  | ||||
|     // **FIXED**: Corrected typo 'ax' to 'a' | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第一步:整理方程", | ||||
|         explanation: "将方程整理成标准形式 ax^2+bx+c=0。", | ||||
|         title: '第一步:整理方程', | ||||
|         explanation: r'将方程整理成标准形式 $ax^2+bx+c=0$。', | ||||
|         formula: | ||||
|             "${a}x^2 ${b >= 0 ? '+' : ''} ${b}x ${c >= 0 ? '+' : ''} $c = 0", | ||||
|             '\$\$${a}x^2 ${b >= 0 ? '+' : ''} ${b}x ${c >= 0 ? '+' : ''} $c = 0\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     // 尝试因式分解 (十字相乘法) | ||||
|     if (a == a.round() && b == b.round() && c == c.round()) { | ||||
|       final factors = _tryFactorization(a.toInt(), b.toInt(), c.toInt()); | ||||
|       if (factors != null) { | ||||
|         steps.add( | ||||
|           CalculationStep( | ||||
|             title: "第二步:因式分解法 (十字相乘)", | ||||
|             explanation: "我们发现可以将方程分解为两个一次因式的乘积。", | ||||
|             title: '第二步:因式分解法 (十字相乘)', | ||||
|             explanation: '我们发现可以将方程分解为两个一次因式的乘积。', | ||||
|             formula: factors.formula, | ||||
|           ), | ||||
|         ); | ||||
|  | ||||
|         steps.add( | ||||
|           CalculationStep( | ||||
|             title: "第三步:求解", | ||||
|             explanation: "分别令每个因式等于 0,解出 x。", | ||||
|             formula: "解得 ${factors.solution}", | ||||
|             title: '第三步:求解', | ||||
|             explanation: '分别令每个因式等于 0,解出 x。', | ||||
|             formula: '解得 ${factors.solution}', | ||||
|           ), | ||||
|         ); | ||||
|  | ||||
|         return CalculationResult(steps: steps, finalAnswer: factors.solution); | ||||
|       } else { | ||||
|         steps.add( | ||||
|           CalculationStep( | ||||
|             title: "第二步:选择解法", | ||||
|             explanation: "尝试因式分解失败,我们选择使用求根公式法。", | ||||
|             formula: "\$\\Delta = b^2 - 4ac\$", | ||||
|           ), | ||||
|         ); | ||||
|       } | ||||
|     } else { | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第二步:选择解法", | ||||
|           explanation: "系数包含小数,我们使用求根公式法。", | ||||
|           formula: "\$\\Delta = b^2 - 4ac\$", | ||||
|         ), | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     // 使用求根公式法 | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: '第二步:选择解法', | ||||
|         explanation: '无法进行因式分解,我们选择使用求根公式法。', | ||||
|         formula: r'\$\$\Delta = b^2 - 4ac\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     final delta = b * b - 4 * a * c; | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第三步:计算判别式 (Delta)", | ||||
|         explanation: "\$\\Delta = ($b)^2 - 4 \\cdot ($a) \\cdot ($c) = $delta", | ||||
|         // **FIXED**: Removed unnecessary braces for linter warning | ||||
|         formula: "\$\\Delta = $delta", | ||||
|         title: '第三步:计算判别式 (Delta)', | ||||
|         explanation: | ||||
|             '\$\$\Delta = b^2 - 4ac = ($b)^2 - 4 \cdot ($a) \cdot ($c) = $delta\$\$', | ||||
|         formula: '\$\$\Delta = $delta\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
| @@ -211,40 +194,40 @@ class SolverService { | ||||
|       final x2 = (-b - sqrt(delta)) / (2 * a); | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第四步:应用求根公式", | ||||
|           title: '第四步:应用求根公式', | ||||
|           explanation: | ||||
|               "因为 \$\\Delta > 0\$,方程有两个不相等的实数根。公式: \$x = \\frac{-b \\pm \\sqrt{\\Delta}}{2a}\$", | ||||
|               r'因为 $\Delta > 0$,方程有两个不相等的实数根。公式: $x = \frac{-b \pm \sqrt{\Delta}}{2a}$。', | ||||
|           formula: | ||||
|               "x₁ = ${x1.toStringAsFixed(4)}, x₂ = ${x2.toStringAsFixed(4)}", | ||||
|               '\$\$x_1 = ${x1.toStringAsFixed(4)}, \quad x_2 = ${x2.toStringAsFixed(4)}\$\$', | ||||
|         ), | ||||
|       ); | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
|         finalAnswer: | ||||
|             "x₁ = ${x1.toStringAsFixed(4)}, x₂ = ${x2.toStringAsFixed(4)}", | ||||
|             '\$\$x_1 = ${x1.toStringAsFixed(4)}, \quad x_2 = ${x2.toStringAsFixed(4)}\$\$', | ||||
|       ); | ||||
|     } else if (delta == 0) { | ||||
|       final x = -b / (2 * a); | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第四步:应用求根公式", | ||||
|           explanation: "因为 \$\Delta = 0\$,方程有两个相等的实数根。", | ||||
|           formula: "x₁ = x₂ = ${x.toStringAsFixed(4)}", | ||||
|           title: '第四步:应用求根公式', | ||||
|           explanation: r'因为 $\Delta = 0$,方程有两个相等的实数根。', | ||||
|           formula: '\$\$x_1 = x_2 = ${x.toStringAsFixed(4)}\$\$', | ||||
|         ), | ||||
|       ); | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
|         finalAnswer: "x₁ = x₂ = ${x.toStringAsFixed(4)}", | ||||
|         finalAnswer: '\$\$x_1 = x_2 = ${x.toStringAsFixed(4)}\$\$', | ||||
|       ); | ||||
|     } else { | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第四步:判断解", | ||||
|           explanation: "因为 \$\Delta < 0\$,该方程在实数范围内无解。", | ||||
|           formula: "无实数解", | ||||
|           title: '第四步:判断解', | ||||
|           explanation: r'因为 $\Delta < 0$,该方程在实数范围内无解。', | ||||
|           formula: '无实数解', | ||||
|         ), | ||||
|       ); | ||||
|       return CalculationResult(steps: steps, finalAnswer: "无实数解"); | ||||
|       return CalculationResult(steps: steps, finalAnswer: '无实数解'); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -262,32 +245,44 @@ class SolverService { | ||||
|  | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "原始方程组", | ||||
|         explanation: "这是一个二元一次方程组,我们将使用加减消元法求解。", | ||||
|         title: '原始方程组', | ||||
|         explanation: '这是一个二元一次方程组,我们将使用加减消元法求解。', | ||||
|         formula: | ||||
|             "${a1}x ${b1 >= 0 ? '+' : ''} ${b1}y = $c1  ---(1)\n${a2}x ${b2 >= 0 ? '+' : ''} ${b2}y = $c2  ---(2)", | ||||
|             ''' | ||||
|  | ||||
| egin{cases} | ||||
| ${a1}x ${b1 >= 0 ? '+' : ''} ${b1}y = $c1 & (1) \\ | ||||
| ${a2}x ${b2 >= 0 ? '+' : ''} ${b2}y = $c2 & (2) | ||||
| \\end{cases} | ||||
|  | ||||
| ''', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     final det = a1 * b2 - a2 * b1; | ||||
|     if (det == 0) { | ||||
|       if (a1 * c2 - a2 * c1 == 0) { | ||||
|         return CalculationResult(steps: steps, finalAnswer: "有无穷多解"); | ||||
|       } else { | ||||
|         return CalculationResult(steps: steps, finalAnswer: "无解"); | ||||
|       } | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
|         finalAnswer: a1 * c2 - a2 * c1 == 0 ? '有无穷多解' : '无解', | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     final newA1 = a1 * b2, newC1 = c1 * b2; | ||||
|     final newA2 = a2 * b1, newC2 = c2 * b1; | ||||
|  | ||||
|     // **FIXED**: Wrapped calculations in braces {} for string interpolation | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第一步:消元", | ||||
|         explanation: "为了消去变量 y,将方程(1)两边乘以 $b2\$,方程(2)两边乘以 $b1\$。", | ||||
|         title: '第一步:消元', | ||||
|         explanation: '为了消去变量 y,将方程(1)两边乘以 $b2,方程(2)两边乘以 $b1。', | ||||
|         formula: | ||||
|             "${newA1}x ${b1 * b2 >= 0 ? '+' : ''} ${b1 * b2}y = $newC1  ---(3)\n${newA2}x ${b1 * b2 >= 0 ? '+' : ''} ${b1 * b2}y = $newC2  ---(4)", | ||||
|             ''' | ||||
|  | ||||
| egin{cases} | ||||
| ${newA1}x ${b1 * b2 >= 0 ? '+' : ''} ${b1 * b2}y = $newC1 & (3) \\ | ||||
| ${newA2}x ${b1 * b2 >= 0 ? '+' : ''} ${b1 * b2}y = $newC2 & (4) | ||||
| \\end{cases} | ||||
|  | ||||
| ''', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
| @@ -296,79 +291,96 @@ class SolverService { | ||||
|  | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第二步:相减", | ||||
|         explanation: "将方程(3)减去方程(4),得到一个只含 x 的方程。", | ||||
|         title: '第二步:相减', | ||||
|         explanation: '将方程(3)减去方程(4),得到一个只含 x 的方程。', | ||||
|         formula: | ||||
|             "($newA1 - $newA2)x = $newC1 - $newC2 \n=> ${xCoeff}x = $constCoeff", | ||||
|             '\$\$($newA1 - $newA2)x = $newC1 - $newC2 \Rightarrow ${xCoeff}x = $constCoeff\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     final x = constCoeff / xCoeff; | ||||
|     steps.add( | ||||
|       CalculationStep( | ||||
|         title: "第三步:解出 x", | ||||
|         explanation: "求解上述方程得到 x 的值。", | ||||
|         formula: "x = $x", | ||||
|         title: '第三步:解出 x', | ||||
|         explanation: '求解上述方程得到 x 的值。', | ||||
|         formula: '\$\$x = $x\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     // **FIXED**: Added a check for b1 to avoid division by zero if we substitute into an equation without y. | ||||
|     if (b1.abs() < 1e-9) { | ||||
|       // If b1 is very close to 0, use the second equation | ||||
|       final yCoeff = b2; | ||||
|       final yConst = c2 - a2 * x; | ||||
|       final y = yConst / yCoeff; | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第四步:回代求解 y", | ||||
|           explanation: "将 x = $x 代入原方程(2)中。", | ||||
|           // **FIXED**: Corrected string interpolation for calculations and substitutions | ||||
|           title: '第四步:回代求解 y', | ||||
|           explanation: '将 x = $x 代入原方程(2)中。', | ||||
|           formula: | ||||
|               "${a2}(${x}) + ${b2}y = $c2 \n=> ${a2 * x} + ${b2}y = $c2 \n=> ${b2}y = $c2 - ${a2 * x} \n=> ${b2}y = ${c2 - a2 * x}", | ||||
|               ''' | ||||
|  | ||||
| \\begin{aligned} | ||||
| $a2($x) + ${b2}y &= $c2 \\ | ||||
| ${a2 * x} + ${b2}y &= $c2 \\ | ||||
| ${b2}y &= $c2 - ${a2 * x} \\ | ||||
| ${b2}y &= ${c2 - a2 * x} | ||||
| \\end{aligned} | ||||
|  | ||||
| ''', | ||||
|         ), | ||||
|       ); | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第五步:解出 y", | ||||
|           explanation: "求解得到 y 的值。", | ||||
|           formula: "y = $y", | ||||
|           title: '第五步:解出 y', | ||||
|           explanation: '求解得到 y 的值。', | ||||
|           formula: '\$\$y = $y\$\$', | ||||
|         ), | ||||
|       ); | ||||
|       return CalculationResult(steps: steps, finalAnswer: "x = $x, y = $y"); | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
|         finalAnswer: '\$\$x = $x, \quad y = $y\$\$', | ||||
|       ); | ||||
|     } else { | ||||
|       // Default case, substitute into the first equation | ||||
|       final yCoeff = b1; | ||||
|       final yConst = c1 - a1 * x; | ||||
|       final y = yConst / yCoeff; | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第四步:回代求解 y", | ||||
|           explanation: "将 x = $x 代入原方程(1)中。", | ||||
|           title: '第四步:回代求解 y', | ||||
|           explanation: '将 x = $x 代入原方程(1)中。', | ||||
|           formula: | ||||
|               "${a1}(${x}) + ${b1}y = $c1 \n=> ${a1 * x} + ${b1}y = $c1 \n=> ${b1}y = $c1 - ${a1 * x} \n=> ${b1}y = ${c1 - a1 * x}", | ||||
|               ''' | ||||
|  | ||||
| \\begin{aligned} | ||||
| $a1($x) + ${b1}y &= $c1 \\ | ||||
| ${a1 * x} + ${b1}y &= $c1 \\ | ||||
| ${b1}y &= $c1 - ${a1 * x} \\ | ||||
| ${b1}y &= ${c1 - a1 * x} | ||||
| \\end{aligned} | ||||
|  | ||||
| ''', | ||||
|         ), | ||||
|       ); | ||||
|       steps.add( | ||||
|         CalculationStep( | ||||
|           title: "第五步:解出 y", | ||||
|           explanation: "求解得到 y 的值。", | ||||
|           formula: "y = $y", | ||||
|           title: '第五步:解出 y', | ||||
|           explanation: '求解得到 y 的值。', | ||||
|           formula: '\$\$y = $y\$\$', | ||||
|         ), | ||||
|       ); | ||||
|       return CalculationResult(steps: steps, finalAnswer: "x = $x, y = $y"); | ||||
|       return CalculationResult( | ||||
|         steps: steps, | ||||
|         finalAnswer: '\$\$x = $x, \\quad y = $y\$\$', | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /// ---- 辅助函数 ---- | ||||
|  | ||||
|   /// 展开表达式,例如 (x-1)(x+2) -> x^2+x-2 | ||||
|   String _expandExpressions(String input) { | ||||
|     String result = input; | ||||
|     // 循环直到没有更多的表达式可以展开 | ||||
|     while (true) { | ||||
|       String oldResult = result; | ||||
|  | ||||
|       // 模式1: k*(ax+b)^2, 例如 4(x-1)^2 or (x-1)^2 | ||||
|       final powerMatch = RegExp( | ||||
|         r'(-?\d*\.?\d*)?\(([^)]+)\)\^2', | ||||
|       ).firstMatch(result); | ||||
| @@ -376,11 +388,7 @@ class SolverService { | ||||
|         final kStr = powerMatch.group(1); | ||||
|         double k = 1.0; | ||||
|         if (kStr != null && kStr.isNotEmpty) { | ||||
|           if (kStr == '-') { | ||||
|             k = -1.0; | ||||
|           } else { | ||||
|             k = double.parse(kStr); | ||||
|           } | ||||
|           k = kStr == '-' ? -1.0 : double.parse(kStr); | ||||
|         } | ||||
|  | ||||
|         final factor = powerMatch.group(2)!; | ||||
| @@ -388,18 +396,16 @@ class SolverService { | ||||
|         final a = coeffs[1] ?? 0; | ||||
|         final b = coeffs[0] ?? 0; | ||||
|  | ||||
|         // (ax+b)^2 = a^2*x^2 + 2ab*x + b^2 | ||||
|         final newA = k * a * a; | ||||
|         final newB = k * 2 * a * b; | ||||
|         final newC = k * b * b; | ||||
|  | ||||
|         final expanded = | ||||
|             "${newA}x^2${newB >= 0 ? '+' : ''}${newB}x${newC >= 0 ? '+' : ''}${newC}"; | ||||
|         result = result.replaceFirst(powerMatch.group(0)!, "($expanded)"); | ||||
|         continue; // 重新开始循环以处理嵌套表达式 | ||||
|             '${newA}x^2${newB >= 0 ? '+' : ''}${newB}x${newC >= 0 ? '+' : ''}$newC'; | ||||
|         result = result.replaceFirst(powerMatch.group(0)!, '($expanded)'); | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // 模式2: (ax+b)(cx+d), 例如 (x-3)(x+2) | ||||
|       final factorMulMatch = RegExp( | ||||
|         r'\(([^)]+)\)\(([^)]+)\)', | ||||
|       ).firstMatch(result); | ||||
| @@ -414,21 +420,17 @@ class SolverService { | ||||
|         final c = coeffs2[1] ?? 0; | ||||
|         final d = coeffs2[0] ?? 0; | ||||
|  | ||||
|         // (ax+b)(cx+d) = ac*x^2 + (ad+bc)*x + bd | ||||
|         final newA = a * c; | ||||
|         final newB = a * d + b * c; | ||||
|         final newC = b * d; | ||||
|  | ||||
|         final expanded = | ||||
|             "${newA}x^2${newB >= 0 ? '+' : ''}${newB}x${newC >= 0 ? '+' : ''}${newC}"; | ||||
|         result = result.replaceFirst(factorMulMatch.group(0)!, "($expanded)"); | ||||
|         continue; // 重新开始循环 | ||||
|             '${newA}x^2${newB >= 0 ? '+' : ''}${newB}x${newC >= 0 ? '+' : ''}$newC'; | ||||
|         result = result.replaceFirst(factorMulMatch.group(0)!, '($expanded)'); | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       // 如果在这次迭代中没有改变,则跳出循环 | ||||
|       if (result == oldResult) { | ||||
|         break; | ||||
|       } | ||||
|       if (result == oldResult) break; | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
| @@ -440,18 +442,18 @@ class SolverService { | ||||
|     final leftCoeffs = _parsePolynomial(parts[0]); | ||||
|     final rightCoeffs = _parsePolynomial(parts[1]); | ||||
|  | ||||
|     final a = leftCoeffs[1] ?? 0.0; | ||||
|     final b = leftCoeffs[0] ?? 0.0; | ||||
|     final c = rightCoeffs[1] ?? 0.0; | ||||
|     final d = rightCoeffs[0] ?? 0.0; | ||||
|  | ||||
|     return LinearEquationParts(a, b, c, d); | ||||
|     return LinearEquationParts( | ||||
|       (leftCoeffs[1] ?? 0.0), | ||||
|       (leftCoeffs[0] ?? 0.0), | ||||
|       (rightCoeffs[1] ?? 0.0), | ||||
|       (rightCoeffs[0] ?? 0.0), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Map<int, double> _parsePolynomial(String side) { | ||||
|     final coeffs = <int, double>{}; | ||||
|     final pattern = RegExp( | ||||
|       r'([+-]?(?:\d*\.?\d*))?x(?:\^(\d+))?|([+-]?\d*\.?\d+)', | ||||
|       r'([+-]?(?:\d*\.?\d*)?)x(?:\^(\d+))?|([+-]?\d*\.?\d+)', | ||||
|     ); | ||||
|     var s = side.startsWith('+') || side.startsWith('-') ? side : '+$side'; | ||||
|  | ||||
| @@ -463,11 +465,7 @@ class SolverService { | ||||
|         String coeffStr = match.group(1) ?? '+'; | ||||
|         double coeff = 1.0; | ||||
|         if (coeffStr.isNotEmpty && coeffStr != '+') { | ||||
|           if (coeffStr == '-') { | ||||
|             coeff = -1.0; | ||||
|           } else { | ||||
|             coeff = double.parse(coeffStr); | ||||
|           } | ||||
|           coeff = coeffStr == '-' ? -1.0 : double.parse(coeffStr); | ||||
|         } else if (coeffStr == '-') { | ||||
|           coeff = -1.0; | ||||
|         } | ||||
| @@ -486,7 +484,7 @@ class SolverService { | ||||
|     final xMatch = RegExp(r'([+-]?\d*\.?\d*)x').firstMatch(parts[0]); | ||||
|     if (xMatch != null) { | ||||
|       final coeff = xMatch.group(1); | ||||
|       if (coeff == null || coeff == '+') { | ||||
|       if (coeff == null || coeff.isEmpty || coeff == '+') { | ||||
|         a = 1.0; | ||||
|       } else if (coeff == '-') { | ||||
|         a = -1.0; | ||||
| @@ -497,7 +495,7 @@ class SolverService { | ||||
|     final yMatch = RegExp(r'([+-]?\d*\.?\d*)y').firstMatch(parts[0]); | ||||
|     if (yMatch != null) { | ||||
|       final coeff = yMatch.group(1); | ||||
|       if (coeff == null || coeff == '+') { | ||||
|       if (coeff == null || coeff.isEmpty || coeff == '+') { | ||||
|         b = 1.0; | ||||
|       } else if (coeff == '-') { | ||||
|         b = -1.0; | ||||
| @@ -523,10 +521,7 @@ class SolverService { | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   // **FIXED**: Simplified check method | ||||
|   bool check(int m, int n, int b) { | ||||
|     return m + n == b; | ||||
|   } | ||||
|   bool check(int m, int n, int b) => m + n == b; | ||||
|  | ||||
|   ({String formula, String solution}) formatFactor(int m, int n, int a) { | ||||
|     int common = gcd(n.abs(), a.abs()); | ||||
| @@ -538,25 +533,23 @@ class SolverService { | ||||
|     final a2 = a ~/ den; | ||||
|     final c2 = m ~/ a2; | ||||
|  | ||||
|     // **FIXED**: Correctly handle coefficients of 1 | ||||
|     final f1Part1 = a1 == 1 ? 'x' : '${a1}x'; | ||||
|     final f1 = c1 == 0 ? f1Part1 : "$f1Part1 ${c1 >= 0 ? '+' : ''} $c1"; | ||||
|     final f1 = c1 == 0 ? f1Part1 : '$f1Part1 ${c1 >= 0 ? '+' : ''} $c1'; | ||||
|  | ||||
|     final f2Part1 = a2 == 1 ? 'x' : '${a2}x'; | ||||
|     final f2 = c2 == 0 ? f2Part1 : "$f2Part1 ${c2 >= 0 ? '+' : ''} $c2"; | ||||
|     final f2 = c2 == 0 ? f2Part1 : '$f2Part1 ${c2 >= 0 ? '+' : ''} $c2'; | ||||
|  | ||||
|     // **FIXED**: Renamed variables to lowerCamelCase | ||||
|     final int x1Num = -c1, x1Den = a1; | ||||
|     final int x2Num = -c2, x2Den = a2; | ||||
|  | ||||
|     final sol1 = x1Den == 1 ? "$x1Num" : "$x1Num/$x1Den"; | ||||
|     final sol2 = x2Den == 1 ? "$x2Num" : "$x2Num/$x2Den"; | ||||
|     final sol1 = x1Den == 1 ? '$x1Num' : '\\frac{$x1Num}{$x1Den}'; | ||||
|     final sol2 = x2Den == 1 ? '$x2Num' : '\\frac{$x2Num}{$x2Den}'; | ||||
|  | ||||
|     final solution = x1Num * x2Den == x2Num * x1Den | ||||
|         ? "x₁ = x₂ = $sol1" | ||||
|         : "x₁ = $sol1, x₂ = $sol2"; | ||||
|         ? 'x_1 = x_2 = $sol1' | ||||
|         : 'x_1 = $sol1, \\quad x_2 = $sol2'; | ||||
|  | ||||
|     return (formula: "(${f1})(${f2}) = 0", solution: solution); | ||||
|     return (formula: '\$\$($f1)($f2) = 0\$\$', solution: '\$\$$solution\$\$'); | ||||
|   } | ||||
|  | ||||
|   int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user