从JAVA中的输入字符串中提取多项式系数

时间:2015-02-18 08:52:21

标签: java

我制作了这个代码,用于提取多项式系数,并在一个点上评估方程,这是有效的。 但我想修改它,以便用户可以输入任何形状的多项式方程。 在我的代码中你必须输入这样的等式:

2*x^2+3*x^1+4

但我想:

2*x^5+1*x+6

如果任何术语具有相同的权力,则必须将它们的系数加在一起。

这是我在java中的代码:

package Priest;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class Equation {

    private String Eq;
    private final String[] C;
    private int Deg;
    private final String EqHolder;

    public Equation(String Equation) {
        this.Eq = Equation;
        EqHolder = Equation;
        Eq = Eq.replaceAll("[^0-9\\-\\.]+", " ");
        Eq = Eq.replaceAll("-", " -");
        this.C = Eq.split(" ");
    }

    public String SourceEquation() {
        return EqHolder.toUpperCase().replaceAll("\\*", "").replaceAll("[a-zA-Z]", "\\*(X)").replaceAll("\\+", "\\ + ").replaceAll("\\-", "\\ - ");
    }

    public List<BigDecimal> CaptureCoeff() {
        getDegree();
        List<BigDecimal> Temp = new ArrayList<>();
        for (String S : C) {
            Temp.add(new BigDecimal(S));
        }
        int Location = Temp.indexOf(BigDecimal.valueOf(Deg));
        List<BigDecimal> Coeffs = new ArrayList<>();
        for (int Counter = Location - 1; Counter < Temp.size(); Counter += 2) {
            Coeffs.add(Temp.get(Counter));
        }
        return Coeffs;
    }

    public int getDegree() {
        int Degree = 0;
        for (int Counter = 0; Counter < C.length; Counter += 2) {
            if ((new Double(C[Counter])) != 0) {
                Degree = new Integer(C[Counter + 1]);
                this.Deg = Degree;
                break;
            }
        }
        return Degree;
    }

    public BigDecimal Evaluate(List<BigDecimal> Coefficients, double EvalPoint) {
        BigDecimal Output = BigDecimal.ZERO;
        for (int Index = 0; Index < Coefficients.size(); Index++) {
            Output = Output.add(Coefficients.get(Index).multiply(BigDecimal.valueOf(EvalPoint).pow(Deg--)));
        }
        return Output;
    }
}

和主要课程:

package Priest;

import java.math.RoundingMode;

public class MainClass {

    public static void main(String[] args) {
        long Start = System.nanoTime();
        String Str = "3.1415x^5-12.6x^4+6x^3+12*x^2-6*x^1-0";
        Equation E = new Equation(Str);
        System.out.println("Equation is: " + E.SourceEquation());
        System.out.println("Coefficients :" + E.CaptureCoeff());
        System.out.println("Polynomial Degree: " + E.getDegree());
        double Target = 47.784;
        System.out.println("Equation @ (X:" + Target + ")= " + E.Evaluate(E.CaptureCoeff(), Target).setScale(15, RoundingMode.HALF_UP));
        System.out.println("Elapsed Time: " + String.format("%.20G", (System.nanoTime() - Start) / 1.0e6) + " ms.");
    }
}

输出:

run:
Equation is: 3.1415*(X)^5 - 12.6*(X)^4 + 6*(X)^3 + 12*(X)^2 - 6*(X)^1 - 0
Coefficients :[3.1415, -12.6, 6, 12, -6, 0]
Polynomial Degree: 5
Equation @ (X:47.784)= 717609084.382589022327914
Elapsed Time: 32.306242000000000000 ms.
BUILD SUCCESSFUL (total time: 0 seconds)

1 个答案:

答案 0 :(得分:0)

我们来看下面的等式String Str2 = "3.1415x^5+6x^2+12*x-5"; 以下是我在代码中添加的代码,以便对此等式进行预处理,并使其与您的实际逻辑兼容,以便在不对代码进行任何重大更改的情况下对其进行处理。

为了完全准确,我必须在等式中更改以下内容:

public List<BigDecimal> CaptureCoeff() {
    getDegree();
    List<BigDecimal> Temp = new ArrayList<BigDecimal>();
    for (String S : C) {
        if (! "".equals(S.trim())) {
            Temp.add(new BigDecimal(S));
        }
    }

所以我添加了控件来检查这些S字符串是否都没有修剪 - 空。

这是我的预处理代码。

我添加了一个名为 powerSplitt 的方法,允许根据'^'字符分割方程式。

然后我创建了另一个名为 generateNullCoeffPolynomeWithDegree 的方法,它以0 * X ^ k的形式生成一个单体。还有一个类似的产生更大功率和更小功率之间的所有类似中间单体的方法

实施例:     String str3 = generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(5,2);     System.out.println(“all poly =”+ str3);

将生成:all poly = 0 * x ^ 4 + 0 * x ^ 3

然后我创建了一个 buildPreProcessedPolynome ,它接受初始等式并预先处理它以产生一个带有空单体的内部。然后我就把它交给你的方程式程序,它可以很好地处理它!

以下是在MainClass中完成的代码和调用示例

import java.math.RoundingMode;

import java.util.ArrayList; import java.util.List;

公共类MainClass {

private static List<String> workList = new ArrayList<String>();

public static void powerSplitt(String equationText) {

    char[] charsList = equationText.toCharArray();

    boolean foundTargetChar = false;
    int index = 0;

    for (int i = 0; i < charsList.length; i++) {
        index = i;
        if (charsList[i] == '^') {

            foundTargetChar = true;
            break;
        }
    }
    if (foundTargetChar) {

        workList.add(equationText.substring(0, index));
        if (index +1 < equationText.length()) {
            powerSplitt(equationText.substring(index+1));
        } else {
            workList.add(equationText);
            return;
        }
    } else {
        workList.add(equationText);
    }

}


public static String generateNullCoeffPolynomeWithDegree(int degree) {
    return "0*x^" + degree;
}

public static String generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(int startDegree, int endDegree) {
    if (startDegree-endDegree <= 1) {
        return "";
    }

    int index = 0;
    StringBuilder builder = new StringBuilder();
    for (int i = startDegree -1; i > endDegree; i--) {
        if (index > 0) {
            builder.append("+");
        }
        builder.append(generateNullCoeffPolynomeWithDegree(i));
        index++;
    }

    return builder.toString();
}

public static String buildPreProcessedPolynome(String initialEquationText) {
    workList.clear();
    powerSplitt(initialEquationText);


    StringBuilder resultBuilder = new StringBuilder();
    assert workList.size() >= 3;
    resultBuilder.append(workList.get(0));

    for (int i = 1; i <= workList.size()-2; i++) {
        int actualPower = Integer.parseInt( workList.get(i).substring(0,1));

        int nextFoundPower = Integer.parseInt( workList.get(i+1).substring(0,1));
        System.out.print("actual power = " + actualPower + " and next power = " + nextFoundPower);
        System.out.println();

        String additionalPolyParts = generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(actualPower, nextFoundPower);
        resultBuilder.append("^" + actualPower);
        resultBuilder.append("+");
        resultBuilder.append(additionalPolyParts);
        resultBuilder.append(workList.get(i).substring(1));

    }

    resultBuilder.append("^" + workList.get(workList.size()-1));
    return resultBuilder.toString();
}

public static void main(String[] args) {
    workList.clear();

    String Str2 = "3.1415x^5+6x^2+12*x-5";

    powerSplitt(Str2);

    for (String part: workList) {
        System.out.println("PART:"  + part);
    }

    System.out.println("-----------------");

    long Start = System.nanoTime();

    String str3 = generateAllNullCoeffPolynomesWithDegreeExclusiveBetween(5, 2);
    System.out.println("all poly = " + str3);

    String preprocessed = buildPreProcessedPolynome(Str2);
    System.out.println("preprocessed = " + preprocessed);

    System.out.println();

    Equation E = new Equation(preprocessed);
    System.out.println("Equation is: " + E.SourceEquation());
    System.out.println("Coefficients :" + E.CaptureCoeff());
    System.out.println("Polynomial Degree: " + E.getDegree());
    double Target = 47.784;
    System.out.println("Equation @ (X:" + Target + ")= " + E.Evaluate(E.CaptureCoeff(), Target).setScale(15, RoundingMode.HALF_UP));
    System.out.println("Elapsed Time: " + String.format("%.20G", (System.nanoTime() - Start) / 1.0e6) + " ms.");
}

}

这是生成的结果(我添加了一些System.out.println来检查我的方法调用的结果。我只是注意到我必须考虑最后一个常量作为K * X ^ 0类型的单体,但我会把它留给你):

  

PART:3.1415x   PART:5 + 6×

     

PART:2 + 12 * X-5

     

所有poly = 0 * x ^ 4 + 0 * x ^ 3   实际功率= 5,下一次功率= 2   preprocessed = 3.1415x ^ 5 + 0 * x ^ 4 + 0 * x ^ 3 + 6x ^ 2 + 12 * x-5

     

公式为:3.1415 *(X)^ 5 + 0 *(X)^ 4 + 0 *(X)^ 3 + 6 *(X)^ 2 + 12 *(X) - 5   系数:[3.1415,0,0,6,12]   多项式学位:5   等式@(X:47.784)= 782631805.485054892561514   经历时间:18,441978000000000000 ms。