【问题标题】:Quadractic equation string processing in JavaJava中的二次方程字符串处理
【发布时间】:2017-03-09 13:59:09
【问题描述】:
  1. 我有一个问题,我们如何重写下面的代码,以便当用户输入这样的字符串5.6x^2+6x-3= -8x^2 + 2x - 5时,程序也可以适应。我知道我们可以通过正则表达式来解决这个问题,但是= 符号似乎阻碍了我的很多思考。

  2. 如果我想提取 co-eficients 并将它们放在一个类似这个伪代码的数组中,我应该如何修复下面的代码?

    arrayOfx^2[]={5.6, -8}
    arrayOfx^1[]={6, 2}
    arrayOfX^0[]={-3, -5}
    

这两个问题的主要原因是我正在考虑制作一个可以为这样的二次方程提供逐步解的应用程序。答案可能类似于“将 5.6x^2 和 -8x^2 的系数结合在一起,得到 13.6x^2”,这比只给用户答案更具教学意义.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ParseEquation_test {

    /**
     * @param str
     * @param regex
     * @return
     */
    public static String coeff(String str, String regex) {
        Pattern patt = Pattern.compile(regex);
        Matcher match = patt.matcher(str);
        // missing coefficient default
        String coeff = "+0";
        double value = 0;

        if (match.find()) {
            coeff = match.group(1);
        }
        // always have sign, handle implicit 1
        value = Double.parseDouble((coeff.length() == 1) ? coeff + "1"
                : coeff);

        while (match.find()) {

            coeff = match.group(1);
            value = value + Double.parseDouble(coeff);
        }
        String value2 = String.valueOf(value);
        return (value2.length() == 1) ? (value2 + "1") : value2;
    }

    public static String[] quadParse(String arg) {
        String str = ("+" + arg).replaceAll("\\s", "");

        double a1 = Double.parseDouble(coeff(str, "([+-][0-9]*)([a-z]\\^2)"));
        double b1 = Double.parseDouble(coeff(str, "([+-][0-9]*)([a-z](?!\\^))"));
        double c1 = Double.parseDouble(coeff(str, "([+-][0-9]+)(?![a-z])"));
        System.out.println("Values are a: " + a1 + " b: " + b1 + " c: " + c1);
        if (a1 == 0) {
            if (b1 == 0) {
                if (c1 == 0) {
                    String no_sol = "There are no solution";
                    return new String[]{no_sol};
                } else {
                    String infinite_sol = "There are infinitely many solutions";
                    return new String[]{infinite_sol};
                }
            } else {
                double sol_order1 = -c1 / b1;
                String final_sol_order1 = Double.toString(sol_order1);
                return new String[]{final_sol_order1};
            }
        } else {

            double dis = (Math.pow(b1, 2.0)) - (4 * a1 * c1);
            double d = Math.sqrt(dis);
            double X = 0, Y = 0; //root 1 & root 2, respectively

            if (dis > 0.0) {
                X = (-b1 + d) / (2.0 * a1);
                Y = (-b1 - d) / (2.0 * a1);
                String root1 = Double.toString(X);
                String root2 = Double.toString(Y);
                return new String[]{root1, root2};
            } else if (dis == 0.0) {
                X = (-b1 + 0.0) / (2.0 * a1);//repeated root
                String root2 = Double.toString(X);
                return new String[]{root2};
            } else if (dis < 0) {
                String no_sol = "There are no solution";
                return new String[]{no_sol};
            }
        }
        return new String[-1];
    }

    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        System.out.println("Insert equation: ");
        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        String s;
        while ((s = r.readLine()) != null) {
            String[] pieces = quadParse(s);
            System.out.println(Arrays.toString(pieces));

        }
    }
}

与这个问题相关的帖子可以在这里找到:

parsing a quadratic equation in java

我还稍微修改了原始代码,使其也可以一阶单变量方程和二次方程。

【问题讨论】:

  • = 和其他字符一样。我建议你先拆分这个字符,然后解析左右两边。然后将[5.6, 6, -3][-8, 2, - 5] 相减得到[13.6, 4, 2] 并作为二次方程求解。
  • 提供逐步解决方案可能会非常困难。也许这对于一个启动程序来说有点太难了?
  • 哦,我只是尝试以鸭带的方式打印二次方程的一些步骤,并没有真正概括所有内容

标签: java regex string input


【解决方案1】:

正如 Peter Lawrey 所说,由 = 拆分,然后分别处理等式的两边。这可以通过以下方式完成。


为了提取系数和指数,您可以使用下面的正则表达式。不过,您需要针对 Java 进行调整(即转义 \ 等)

(?&lt;coefficient&gt;\[-+\]?(?:\d+\.)?\d+)(?:\[x\]\[\^\](?&lt;exponent&gt;\d))?

它匹配一个整数或十进制数,它作为第一组提取,称为系数,后跟一个带指数的变量。

指数由第二组捕获,称为指数,是可选的。因为它被放在一个非捕获组 (?: ...) 中,它是可选的,带有 ? 后缀(即只允许出现 0 或 1 次)。

针对5.6x^2 +6x -3 进行测试会产生三个匹配项。

Match 1
Full match  0-6 `5.6x^2`
Group `coefficient` 0-3 `5.6`
Group `exponent`    5-6 `2`

Match 2
Full match  6-8 `+6`
Group `coefficient` 6-8 `+6`

Match 3
Full match  9-11    `-3`
Group `coefficient` 9-11    `-3`

如您所见,匹配+6x 中的隐式^1 仍然存在问题。您可以通过预处理字符串并将每个独立的x 替换为x^1 来解决问题。

此外,符号和数字之间的空格(例如 - 6x^1 而不是 -6x^1)会导致符号被跳过,因此应在预处理期间将其删除。


处理完等式的两边后,您可以将系数和指数表示为数组,并在众多求解等式的算法中轻松使用它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 2020-02-26
    • 2010-11-01
    相关资源
    最近更新 更多