线性方程的解析系数

时间:2015-08-19 10:43:46

标签: java parsing calculator coefficients linear-equation

在java中我试图找到线性方程的系数,以便在我的计算器应用程序中找到线性方程的解,例如:

3x +2*(6x-3) = 2 -4x 

我最想得到的是x的系数和ax+b =0形式的常数,

在这个特定的例子中

coefficient = 19
constant = -8

请提出一个概括性的想法

1 个答案:

答案 0 :(得分:2)

正如我的评论所暗示的那样:这可能是任意复杂的,取决于这个解析器应该支持的。这里涉及几个可能非常复杂和具有挑战性的任务。

第一个是解析本身。虽然它很好理解并且有编写解析器和所有的支持工具,但是从头开始为这些表达式编写一个健壮,可靠的解析器将是单调乏味的(并且需要付出一些努力)。

第二个是简化表达式。虽然人们可以编写一个简单的解析器(或使用现有的解析器),但人们可能(乍一看)认为有必要对生成的AST进行操作以找到实际的常数和系数 - 例如我们可以认为有必要应用分布定律,找到共同因素,将等式从公式的一边转移到另一边等等。

幸运的是,这一切都没有必要: - )

您可以使用任意解析器来解析方程中涉及的表达式。其中一个最着名的解析器是JEP, the Java Expression Parser(这不是推荐 - 我只是知道它,它似乎运作良好)。顾名思义,它只是一个 Expression 解析器,而不是 Equation 解析器。但是这个等式可以简单地在=处拆分,以获得两个可以单独解析的表达式。

这两个表达式不足以找到系数和常数。但是在这里,一个小的(脏的)技巧开始发挥作用:你可以通过评估这些表达式来推导系数和常数。特别是,您可以设置x=0以分别确定左侧和右侧的常量部分。然后,您可以设置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