线性方程的解析系数
Parse Coefficient of an Linear equation
在 java 中,我试图找到线性方程的系数,以便在我的计算器应用程序中找到线性方程的解,例如:
3x +2*(6x-3) = 2 -4x
我非常想得到的是 x 的系数和 ax+b =0
,
形式的常数
在此特定示例中
coefficient = 19
constant = -8
请提出一个通用的想法
正如我的评论所暗示的那样:这可能是任意复杂的,具体取决于 这个解析器应该支持什么。这里涉及几个可能非常复杂和具有挑战性的任务。
第一个是解析本身。虽然它很好理解并且有用于编写解析器和所有工具的支持工具,但是为这些表达式从头开始编写一个健壮、可靠的解析器将是乏味的(并且需要付出一些努力)。 =17=]
第二个是简化表达式。虽然可以编写一个简单的解析器(或使用现有的解析器),但可能(乍一看)认为有必要对生成的 AST 进行操作以找到实际的常量和系数——例如人们可能会认为有必要应用分布规律,找到公因数,将部分表达式从等式的一侧转移到另一侧等等。
幸运的是,这一切都不是必需的:-)
您可以使用任意解析器来解析等式中涉及的表达式。最著名的解析器之一是 JEP, the Java Expression Parser(这不是推荐 - 我只是知道它,而且它似乎运行良好)。顾名思义,它只是一个 Expression 解析器,而不是 Equation 解析器。但是方程式可以简单地在 =
处拆分,以获得两个可以单独解析的表达式。
这两个表达式不足以求出系数和常数。但是在这里,一个小的(肮脏的?)技巧开始发挥作用:您可以通过 评估 这些表达式来导出系数和常数。特别是,你可以一次设置x=0
来分别确定左侧和右侧的constant部分。然后,您可以设置 x=1
,计算结果表达式,并减去常数以获得 系数 。
由两边的系数和常数,可以计算出整个方程的系数和常数。这是在这里实现的,作为 MCVE:
import org.nfunk.jep.JEP;
public class LinearEquationParser
{
private double coefficient;
private double constant;
public static void main(String[] args)
{
runTest("3x = 5");
runTest("3x +2*(6x-3) = 2 -4x");
runTest("3x + 2*(6x -sin(3))=cos(2)-4*x*log(tan(43))");
}
private static void runTest(String s)
{
System.out.println("Input: "+s);
LinearEquationParser p = new LinearEquationParser();
p.process(s);
System.out.println("Coefficient: "+p.getCoefficient());
System.out.println("Constant : "+p.getConstant());
System.out.println();
}
public void process(String s)
{
JEP jep = new JEP();
jep.setImplicitMul(true);
jep.addStandardFunctions();
jep.addStandardConstants();
jep.addVariable("x", 0.0);
String s0 = s.substring(0, s.indexOf("="));
String s1 = s.substring(s.indexOf("=")+1, s.length());
jep.parseExpression(s0);
if (jep.hasError())
{
throw new IllegalArgumentException(jep.getErrorInfo());
}
jep.addVariable("x", 0.0);
double constant0 = jep.getValue();
jep.addVariable("x", 1.0);
double value0 = jep.getValue();
jep.parseExpression(s1);
if (jep.hasError())
{
throw new IllegalArgumentException(jep.getErrorInfo());
}
jep.addVariable("x", 0.0);
double constant1 = jep.getValue();
jep.addVariable("x", 1.0);
double value1 = jep.getValue();
constant = constant0 - constant1;
coefficient = (value0 - constant0) - (value1-constant1);
}
public double getCoefficient()
{
return coefficient;
}
public double getConstant()
{
return constant;
}
}
输出如愿:
Input: 3x = 5
Coefficient: 3.0
Constant : -5.0
Input: 3x +2*(6x-3) = 2 -4x
Coefficient: 19.0
Constant : -8.0
Input: 3x + 2*(6x -sin(3))=cos(2)-4*x*log(tan(43))
Coefficient: 15.7024963786418
Constant : 0.13390682042740798
在 java 中,我试图找到线性方程的系数,以便在我的计算器应用程序中找到线性方程的解,例如:
3x +2*(6x-3) = 2 -4x
我非常想得到的是 x 的系数和 ax+b =0
,
在此特定示例中
coefficient = 19
constant = -8
请提出一个通用的想法
正如我的评论所暗示的那样:这可能是任意复杂的,具体取决于 这个解析器应该支持什么。这里涉及几个可能非常复杂和具有挑战性的任务。
第一个是解析本身。虽然它很好理解并且有用于编写解析器和所有工具的支持工具,但是为这些表达式从头开始编写一个健壮、可靠的解析器将是乏味的(并且需要付出一些努力)。 =17=]
第二个是简化表达式。虽然可以编写一个简单的解析器(或使用现有的解析器),但可能(乍一看)认为有必要对生成的 AST 进行操作以找到实际的常量和系数——例如人们可能会认为有必要应用分布规律,找到公因数,将部分表达式从等式的一侧转移到另一侧等等。
幸运的是,这一切都不是必需的:-)
您可以使用任意解析器来解析等式中涉及的表达式。最著名的解析器之一是 JEP, the Java Expression Parser(这不是推荐 - 我只是知道它,而且它似乎运行良好)。顾名思义,它只是一个 Expression 解析器,而不是 Equation 解析器。但是方程式可以简单地在 =
处拆分,以获得两个可以单独解析的表达式。
这两个表达式不足以求出系数和常数。但是在这里,一个小的(肮脏的?)技巧开始发挥作用:您可以通过 评估 这些表达式来导出系数和常数。特别是,你可以一次设置x=0
来分别确定左侧和右侧的constant部分。然后,您可以设置 x=1
,计算结果表达式,并减去常数以获得 系数 。
由两边的系数和常数,可以计算出整个方程的系数和常数。这是在这里实现的,作为 MCVE:
import org.nfunk.jep.JEP;
public class LinearEquationParser
{
private double coefficient;
private double constant;
public static void main(String[] args)
{
runTest("3x = 5");
runTest("3x +2*(6x-3) = 2 -4x");
runTest("3x + 2*(6x -sin(3))=cos(2)-4*x*log(tan(43))");
}
private static void runTest(String s)
{
System.out.println("Input: "+s);
LinearEquationParser p = new LinearEquationParser();
p.process(s);
System.out.println("Coefficient: "+p.getCoefficient());
System.out.println("Constant : "+p.getConstant());
System.out.println();
}
public void process(String s)
{
JEP jep = new JEP();
jep.setImplicitMul(true);
jep.addStandardFunctions();
jep.addStandardConstants();
jep.addVariable("x", 0.0);
String s0 = s.substring(0, s.indexOf("="));
String s1 = s.substring(s.indexOf("=")+1, s.length());
jep.parseExpression(s0);
if (jep.hasError())
{
throw new IllegalArgumentException(jep.getErrorInfo());
}
jep.addVariable("x", 0.0);
double constant0 = jep.getValue();
jep.addVariable("x", 1.0);
double value0 = jep.getValue();
jep.parseExpression(s1);
if (jep.hasError())
{
throw new IllegalArgumentException(jep.getErrorInfo());
}
jep.addVariable("x", 0.0);
double constant1 = jep.getValue();
jep.addVariable("x", 1.0);
double value1 = jep.getValue();
constant = constant0 - constant1;
coefficient = (value0 - constant0) - (value1-constant1);
}
public double getCoefficient()
{
return coefficient;
}
public double getConstant()
{
return constant;
}
}
输出如愿:
Input: 3x = 5
Coefficient: 3.0
Constant : -5.0
Input: 3x +2*(6x-3) = 2 -4x
Coefficient: 19.0
Constant : -8.0
Input: 3x + 2*(6x -sin(3))=cos(2)-4*x*log(tan(43))
Coefficient: 15.7024963786418
Constant : 0.13390682042740798