💄 🤔
This commit is contained in:
		
							
								
								
									
										149
									
								
								lib/solver.dart
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								lib/solver.dart
									
									
									
									
									
								
							| @@ -59,15 +59,24 @@ class SolverService { | ||||
|         stepNumber: 1, | ||||
|         title: '表达式求值', | ||||
|         explanation: '这是一个标准的数学表达式,我们将直接计算其结果。', | ||||
|         formula: input, | ||||
|         formula: '\$\$$input\$\$', | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
|     GrammarParser p = GrammarParser(); | ||||
|     Expression exp = p.parse(input); | ||||
|     final result = RealEvaluator().evaluate(exp); | ||||
|     // 预处理平方根符号 | ||||
|     final processedInput = _preprocessSqrt(input); | ||||
|  | ||||
|     return CalculationResult(steps: steps, finalAnswer: result.toString()); | ||||
|     GrammarParser p = GrammarParser(); | ||||
|     Expression exp = p.parse(processedInput); | ||||
|     final result = RealEvaluator().evaluate(exp).toDouble(); | ||||
|  | ||||
|     // 尝试将结果格式化为几倍根号的形式 | ||||
|     final formattedResult = _formatSqrtResult(result); | ||||
|  | ||||
|     return CalculationResult( | ||||
|       steps: steps, | ||||
|       finalAnswer: '\$\$$formattedResult\$\$', | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /// 2. 求解一元一次方程 | ||||
| @@ -422,6 +431,81 @@ ${b1}y &= ${c1 - a1 * x} | ||||
|  | ||||
|   /// ---- 辅助函数 ---- | ||||
|  | ||||
|   /// 将数值结果格式化为几倍根号的形式 | ||||
|   String _formatSqrtResult(double result) { | ||||
|     // 处理负数 | ||||
|     if (result < 0) { | ||||
|       return '-${_formatSqrtResult(-result)}'; | ||||
|     } | ||||
|  | ||||
|     // 处理零 | ||||
|     if (result == 0) return '0'; | ||||
|  | ||||
|     // 检查是否接近整数 | ||||
|     final rounded = result.round(); | ||||
|     if ((result - rounded).abs() < 1e-10) { | ||||
|       return rounded.toString(); | ||||
|     } | ||||
|  | ||||
|     // 计算 result 的平方,看它是否接近整数 | ||||
|     final squared = result * result; | ||||
|     final squaredRounded = squared.round(); | ||||
|  | ||||
|     // 如果 squared 接近整数,说明 result 是某个数的平方根 | ||||
|     if ((squared - squaredRounded).abs() < 1e-6) { | ||||
|       // 寻找最大的完全平方数因子 | ||||
|       int maxSquareFactor = 1; | ||||
|       for (int i = 2; i * i <= squaredRounded; i++) { | ||||
|         if (squaredRounded % (i * i) == 0) { | ||||
|           maxSquareFactor = i * i; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       final coefficient = sqrt(maxSquareFactor).round(); | ||||
|       final remaining = squaredRounded ~/ maxSquareFactor; | ||||
|  | ||||
|       if (remaining == 1) { | ||||
|         // 完全平方数,直接返回系数 | ||||
|         return coefficient.toString(); | ||||
|       } else if (coefficient == 1) { | ||||
|         return '\\sqrt{$remaining}'; | ||||
|       } else { | ||||
|         return '$coefficient\\sqrt{$remaining}'; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // 如果不是平方根的结果,返回原始数值(保留几位小数) | ||||
|     return result | ||||
|         .toStringAsFixed(6) | ||||
|         .replaceAll(RegExp(r'\.0+$'), '') | ||||
|         .replaceAll(RegExp(r'\.$'), ''); | ||||
|   } | ||||
|  | ||||
|   /// 预处理平方根表示法,将 \sqrt{expr} 转换为 sqrt(expr) | ||||
|   String _preprocessSqrt(String input) { | ||||
|     // 使用正则表达式替换 \sqrt{expr} 为 sqrt(expr) | ||||
|     // 处理嵌套的情况,使用循环直到没有更多匹配 | ||||
|     String result = input; | ||||
|     int maxIterations = 10; // 防止无限循环 | ||||
|     int iterationCount = 0; | ||||
|  | ||||
|     while (iterationCount < maxIterations) { | ||||
|       String oldResult = result; | ||||
|       result = result.replaceAllMapped( | ||||
|         RegExp(r'\\sqrt\{([^}]+)\}'), | ||||
|         (match) => 'sqrt(${match.group(1)})', | ||||
|       ); | ||||
|       if (result == oldResult) break; | ||||
|       iterationCount++; | ||||
|     } | ||||
|  | ||||
|     if (iterationCount >= maxIterations) { | ||||
|       throw Exception('平方根表达式过于复杂,请简化输入。'); | ||||
|     } | ||||
|  | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   String _expandExpressions(String input) { | ||||
|     String result = input; | ||||
|     int maxIterations = 10; // Prevent infinite loops | ||||
| @@ -544,29 +628,68 @@ ${b1}y &= ${c1 - a1 * x} | ||||
|  | ||||
|   Map<int, double> _parsePolynomial(String side) { | ||||
|     final coeffs = <int, double>{}; | ||||
|     // 扩展模式以支持 sqrt 函数 | ||||
|     final pattern = RegExp( | ||||
|       r'([+-]?(?:\d*\.?\d*)?)x(?:\^(\d+))?|([+-]?\d*\.?\d+)', | ||||
|       r'([+-]?(?:\d*\.?\d*|sqrt\(\d+\)))x(?:\^(\d+))?|([+-]?(?:\d*\.?\d*|sqrt\(\d+\)))', | ||||
|     ); | ||||
|     var s = side.startsWith('+') || side.startsWith('-') ? side : '+$side'; | ||||
|  | ||||
|     for (final match in pattern.allMatches(s)) { | ||||
|       if (match.group(3) != null) { | ||||
|         coeffs[0] = (coeffs[0] ?? 0) + double.parse(match.group(3)!); | ||||
|         // 常数项 | ||||
|         final constStr = match.group(3)!; | ||||
|         final constValue = _parseCoefficientWithSqrt(constStr); | ||||
|         coeffs[0] = (coeffs[0] ?? 0) + constValue; | ||||
|       } else { | ||||
|         // x 的幂次项 | ||||
|         int power = match.group(2) != null ? int.parse(match.group(2)!) : 1; | ||||
|         String coeffStr = match.group(1) ?? '+'; | ||||
|         double coeff = 1.0; | ||||
|         if (coeffStr.isNotEmpty && coeffStr != '+') { | ||||
|           coeff = coeffStr == '-' ? -1.0 : double.parse(coeffStr); | ||||
|         } else if (coeffStr == '-') { | ||||
|           coeff = -1.0; | ||||
|         } | ||||
|         final coeff = _parseCoefficientWithSqrt(coeffStr); | ||||
|         coeffs[power] = (coeffs[power] ?? 0) + coeff; | ||||
|       } | ||||
|     } | ||||
|     return coeffs; | ||||
|   } | ||||
|  | ||||
|   /// 解析包含 sqrt 函数的系数 | ||||
|   double _parseCoefficientWithSqrt(String coeffStr) { | ||||
|     if (coeffStr.isEmpty || coeffStr == '+') return 1.0; | ||||
|     if (coeffStr == '-') return -1.0; | ||||
|  | ||||
|     // 检查是否包含 sqrt 函数 | ||||
|     final sqrtMatch = RegExp(r'sqrt\((\d+)\)').firstMatch(coeffStr); | ||||
|     if (sqrtMatch != null) { | ||||
|       final innerValue = int.parse(sqrtMatch.group(1)!); | ||||
|  | ||||
|       // 对于完全平方数,直接返回整数结果 | ||||
|       final sqrtValue = sqrt(innerValue.toDouble()); | ||||
|       final rounded = sqrtValue.round(); | ||||
|       if ((sqrtValue - rounded).abs() < 1e-10) { | ||||
|         // 检查是否有系数 | ||||
|         final coeffPart = coeffStr.replaceFirst(sqrtMatch.group(0)!, ''); | ||||
|         if (coeffPart.isEmpty) return rounded.toDouble(); | ||||
|         if (coeffPart == '-') return -rounded.toDouble(); | ||||
|  | ||||
|         final coeff = double.parse(coeffPart); | ||||
|         return coeff * rounded; | ||||
|       } | ||||
|  | ||||
|       // 对于非完全平方数,计算数值但保持高精度 | ||||
|       final nonPerfectSqrtValue = sqrt(innerValue.toDouble()); | ||||
|  | ||||
|       // 检查是否有系数 | ||||
|       final coeffPart = coeffStr.replaceFirst(sqrtMatch.group(0)!, ''); | ||||
|       if (coeffPart.isEmpty) return nonPerfectSqrtValue; | ||||
|       if (coeffPart == '-') return -nonPerfectSqrtValue; | ||||
|  | ||||
|       final coeff = double.parse(coeffPart); | ||||
|       return coeff * nonPerfectSqrtValue; | ||||
|     } | ||||
|  | ||||
|     // 普通数值 | ||||
|     return double.parse(coeffStr); | ||||
|   } | ||||
|  | ||||
|   List<double> _parseTwoVariableLinear(String equation) { | ||||
|     final parts = equation.split('='); | ||||
|     if (parts.length != 2) throw Exception("方程 $equation 格式错误"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user