🐛 Fix expressions
This commit is contained in:
171
lib/solver.dart
171
lib/solver.dart
@@ -401,25 +401,6 @@ class SolverService {
|
|||||||
final eqParts = input.split('=');
|
final eqParts = input.split('=');
|
||||||
if (eqParts.length != 2) throw Exception("方程格式错误,应包含一个 '='。");
|
if (eqParts.length != 2) throw Exception("方程格式错误,应包含一个 '='。");
|
||||||
|
|
||||||
// Keep original equation for display
|
|
||||||
final originalEquation = _formatOriginalEquation(input);
|
|
||||||
|
|
||||||
// Parse coefficients symbolically (kept for potential future use)
|
|
||||||
// final leftCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[0]);
|
|
||||||
// final rightCoeffsSymbolic = _parsePolynomialSymbolic(eqParts[1]);
|
|
||||||
// final aSymbolic = _subtractCoefficients(
|
|
||||||
// leftCoeffsSymbolic[2] ?? '0',
|
|
||||||
// rightCoeffsSymbolic[2] ?? '0',
|
|
||||||
// );
|
|
||||||
// final bSymbolic = _subtractCoefficients(
|
|
||||||
// leftCoeffsSymbolic[1] ?? '0',
|
|
||||||
// rightCoeffsSymbolic[1] ?? '0',
|
|
||||||
// );
|
|
||||||
// final cSymbolic = _subtractCoefficients(
|
|
||||||
// leftCoeffsSymbolic[0] ?? '0',
|
|
||||||
// rightCoeffsSymbolic[0] ?? '0',
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Also get numeric values for calculations
|
// Also get numeric values for calculations
|
||||||
final leftCoeffs = _parsePolynomial(eqParts[0], variable);
|
final leftCoeffs = _parsePolynomial(eqParts[0], variable);
|
||||||
final rightCoeffs = _parsePolynomial(eqParts[1], variable);
|
final rightCoeffs = _parsePolynomial(eqParts[1], variable);
|
||||||
@@ -431,12 +412,15 @@ class SolverService {
|
|||||||
return _solveLinearEquation('${b}x+$c=0');
|
return _solveLinearEquation('${b}x+$c=0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create expanded equation display
|
||||||
|
final expandedEquation = _formatExpandedEquation(input);
|
||||||
|
|
||||||
steps.add(
|
steps.add(
|
||||||
CalculationStep(
|
CalculationStep(
|
||||||
stepNumber: 1,
|
stepNumber: 1,
|
||||||
title: '整理方程',
|
title: '整理方程',
|
||||||
explanation: r'将方程整理成标准形式 $ax^2+bx+c=0$。',
|
explanation: r'将方程整理成标准形式 $ax^2+bx+c=0$。',
|
||||||
formula: originalEquation,
|
formula: expandedEquation,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1406,136 +1390,59 @@ ${b1}y &= ${c1 - a1 * x.toDouble()}
|
|||||||
|
|
||||||
int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b);
|
int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b);
|
||||||
|
|
||||||
/// 格式化原始方程,保持符号形式
|
/// 格式化展开后的方程
|
||||||
String _formatOriginalEquation(String input) {
|
String _formatExpandedEquation(String input) {
|
||||||
// Parse the equation and convert to LaTeX
|
// The input is already expanded, so we just need to format it for LaTeX display
|
||||||
String result = input.replaceAll(' ', '');
|
String result = input.replaceAll(' ', '');
|
||||||
|
|
||||||
// 确保方程格式正确
|
// Ensure equation format is correct
|
||||||
if (!result.contains('=')) {
|
if (!result.contains('=')) {
|
||||||
result = '$result=0';
|
result = '$result=0';
|
||||||
}
|
}
|
||||||
|
|
||||||
final parts = result.split('=');
|
final parts = result.split('=');
|
||||||
if (parts.length == 2) {
|
if (parts.length == 2) {
|
||||||
// Check if the equation is already in standard polynomial form
|
// Clean up the expanded expression directly without re-parsing
|
||||||
// If it doesn't contain parentheses and looks like a standard polynomial,
|
// to avoid adding unnecessary parentheses
|
||||||
// return it as-is to avoid unnecessary parsing
|
String leftStr = _cleanExpandedExpressionForDisplay(parts[0]);
|
||||||
final leftSide = parts[0];
|
String rightStr = _cleanExpandedExpressionForDisplay(parts[1]);
|
||||||
final rightSide = parts[1];
|
|
||||||
|
|
||||||
// If left side is a standard polynomial (no parentheses, only x^2, x, and constants)
|
result = '$leftStr=$rightStr';
|
||||||
// and right side is 0, return the original
|
|
||||||
if (_isStandardPolynomial(leftSide) &&
|
|
||||||
(rightSide == '0' || rightSide.isEmpty)) {
|
|
||||||
result = '$leftSide=0';
|
|
||||||
return '\$\$$result\$\$';
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final leftParser = Parser(parts[0]);
|
|
||||||
final leftExpr = leftParser.parse();
|
|
||||||
final rightParser = Parser(parts[1]);
|
|
||||||
final rightExpr = rightParser.parse();
|
|
||||||
|
|
||||||
// Get the string representation and clean it up
|
|
||||||
String leftStr = leftExpr.toString().replaceAll('*', '\\cdot');
|
|
||||||
String rightStr = rightExpr.toString().replaceAll('*', '\\cdot');
|
|
||||||
|
|
||||||
// Clean up unnecessary parentheses
|
|
||||||
leftStr = _cleanParentheses(leftStr);
|
|
||||||
rightStr = _cleanParentheses(rightStr);
|
|
||||||
|
|
||||||
result = '$leftStr=$rightStr';
|
|
||||||
} catch (e) {
|
|
||||||
// Fallback to original if parsing fails
|
|
||||||
result = result.replaceAll('sqrt(', '\\sqrt{');
|
|
||||||
result = result.replaceAll(')', '}');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
final parser = Parser(result.split('=')[0]);
|
|
||||||
final expr = parser.parse();
|
|
||||||
|
|
||||||
// Get the string representation and clean it up
|
|
||||||
String exprStr = expr.toString().replaceAll('*', '\\cdot');
|
|
||||||
exprStr = _cleanParentheses(exprStr);
|
|
||||||
|
|
||||||
result = '$exprStr=0';
|
|
||||||
} catch (e) {
|
|
||||||
// Fallback
|
|
||||||
result = result.replaceAll('sqrt(', '\\sqrt{');
|
|
||||||
result = result.replaceAll(')', '}');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return '\$\$$result\$\$';
|
return '\$\$$result\$\$';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查字符串是否为标准多项式形式(不含括号,只有x^2、x和常数项)
|
/// 清理展开后的表达式用于显示,去除不必要的括号
|
||||||
bool _isStandardPolynomial(String expr) {
|
String _cleanExpandedExpressionForDisplay(String expr) {
|
||||||
// Remove spaces
|
String result = expr;
|
||||||
final cleanExpr = expr.replaceAll(' ', '');
|
|
||||||
|
|
||||||
// If it contains parentheses, it's not standard
|
// 移除最外层的括号,如果它们包围整个表达式
|
||||||
if (cleanExpr.contains('(') || cleanExpr.contains(')')) {
|
if (result.startsWith('(') && result.endsWith(')')) {
|
||||||
return false;
|
String inner = result.substring(1, result.length - 1);
|
||||||
}
|
// 检查内部是否包含运算符,如果不包含或只包含加减号,可以移除括号
|
||||||
|
if (!inner.contains('*') && !inner.contains('/')) {
|
||||||
// Check if it matches the pattern of a standard polynomial
|
// 对于加减号,检查是否只有一个运算符
|
||||||
// Should only contain: digits, x, ^, +, -, and spaces (already removed)
|
final plusMinusCount =
|
||||||
final validChars = RegExp(r'^[0-9x\^\+\-\.]*$');
|
'+'.allMatches(inner).length + '-'.allMatches(inner).length;
|
||||||
if (!validChars.hasMatch(cleanExpr)) {
|
if (plusMinusCount <= 1) {
|
||||||
return false;
|
result = inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should not have complex expressions like x*x or 2x*3
|
|
||||||
if (cleanExpr.contains('*') || cleanExpr.contains('/')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should have proper x^2 format (not xx or x2)
|
|
||||||
if (cleanExpr.contains('x^2') ||
|
|
||||||
cleanExpr.contains('x^3') ||
|
|
||||||
cleanExpr.contains('x^4')) {
|
|
||||||
// This is likely a polynomial
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for simple terms like x, 2x, x+1, etc.
|
|
||||||
final termPattern = RegExp(
|
|
||||||
r'^[+-]?(?:\d*\.?\d*)?x?(?:\^\d+)?(?:[+-][+-]?(?:\d*\.?\d*)?x?(?:\^\d+)?)*$',
|
|
||||||
);
|
|
||||||
return termPattern.hasMatch(cleanExpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 清理不必要的括号
|
|
||||||
String _cleanParentheses(String expr) {
|
|
||||||
// 移除最外层的括号,如果它们不影响运算顺序
|
|
||||||
if (expr.startsWith('(') && expr.endsWith(')')) {
|
|
||||||
String inner = expr.substring(1, expr.length - 1);
|
|
||||||
|
|
||||||
// 检查移除括号是否会改变含义
|
|
||||||
// 简单检查:如果内部没有运算符,或者只有加减号,可以移除
|
|
||||||
if (!inner.contains('+') &&
|
|
||||||
!inner.contains('-') &&
|
|
||||||
!inner.contains('*') &&
|
|
||||||
!inner.contains('/')) {
|
|
||||||
return inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果内部表达式是简单的,可以移除括号
|
|
||||||
// 例如:(x+1) 可以变成 x+1, 但 (x+1)*(x-1) 不能移除
|
|
||||||
final operators = RegExp(r'[+\-*/]');
|
|
||||||
final matches = operators.allMatches(inner).toList();
|
|
||||||
|
|
||||||
// 如果只有一个运算符且是加减号,可以移除
|
|
||||||
if (matches.length == 1 && (inner.contains('+') || inner.contains('-'))) {
|
|
||||||
return inner;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
// 移除内部不必要的括号
|
||||||
|
result = result.replaceAll('(+', '(');
|
||||||
|
result = result.replaceAll('(-', '(');
|
||||||
|
|
||||||
|
// 格式化乘法符号
|
||||||
|
result = result.replaceAll('*', '\\cdot');
|
||||||
|
|
||||||
|
// 处理根号
|
||||||
|
result = result.replaceAll('sqrt(', '\\sqrt{');
|
||||||
|
result = result.replaceAll(')', '}');
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 清理展开后的表达式格式
|
/// 清理展开后的表达式格式
|
||||||
|
Reference in New Issue
Block a user