【问题标题】:Own String parser java which solves mathematical equations wrote down in a string自己的字符串解析器java,它解决了写在字符串中的数学方程
【发布时间】:2018-07-23 16:29:33
【问题描述】:

我用 Java 编写了一个方法/函数,它返回给定基本方程的结果。这个等式将作为字符串给出,我认为我得到了这个方法,但不知道为什么我需要这一行代码,因为没有它应该可以工作。尝试了一个多小时解决后我放弃了,希望你能给我一个答案。

这里是代码:

    public static double format(String s) {

    char[] c = s.toCharArray();

    if(s.contains("(")) {
        int openbrackets = 0;
        for (int i = 0; i < s.length() - 2; i++) {
            if (c[i] == '(') openbrackets++;
            else if (c[i] == ')') {
                openbrackets--;
                if(openbrackets == 0) {
                    s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
                    break;
                }
            }
        }
    }
    if (s.contains("(")) {    // String can still contains brackets
        s = "" + format(s);
    }

    c = s.toCharArray();
    for(int i = c.length-1; i >= 0; i--) {
        if(c[i] == '+') {
            return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
        } else if(c[i] == '-') {
            return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
        }
    }

    for(int i = s.length()-1; i > 0; i--) {
        if(c[i] == '*') {
            return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
        } else if (c[i] == '/') {
            return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
        }
    }

    return s.equals("") ? 0 : Double.parseDouble(s); // I don't understand why I need to do this line
}

说明: 我不知道为什么我需要这个 s.equals("") ? :因为字符串永远不应该是空的,但是当我用这个方程运行它时 ((23)+(23-23-432-35-1-2-4231+2312+12323-(-3))*3/2)例如,没有它我会得到一个错误。 我需要解析器将配置字符串转换为数字,例如在屏幕分辨率方面。我知道我也可以使用库,但我想自己尝试这些东西。

PS:不要因为我不使用库而讨厌我。我真的很想弄清楚,我很开心。我只是想知道为什么我必须写这个小代码行,因为我不明白......

编辑:错误是 NumberFormatException,因为 Parsing 有一个空字符串...现在我的错误也是 cmets 中提到的 OverflowException...

编辑:对于将来可能会使用这样的东西的每个人: 这里是实际工作的代码:

    public static double format(String s) {
    s = s.replace(" ", "");
    s = s.replace("\t", "");
    char[] c = s.toCharArray();
    if(s.contains("(")) {
        int openbrackets = 0;
        for (int i = 0; i < s.length(); i++) {
            if (c[i] == '(') openbrackets++;
            else if (c[i] == ')') {
                openbrackets--;
                if(openbrackets == 0) {
                    s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
                    break;
                }
            }
        }
    }
    if (s.contains("(")) s = "" + format(s);
    c = s.toCharArray();
    for(int i = c.length-1; i > 0; i--) {
        if(c[i] == '+') {
            return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
        } else if(c[i] == '-') {
            return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
        }
    }
    for(int i = s.length()-1; i > 0; i--) {
        if(c[i] == '*') {
            return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
        } else if (c[i] == '/') {
            return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
        }
    }
    return s.equals("") ? 0 : Double.parseDouble(s);
}

【问题讨论】:

  • 为什么你认为我们会因为你不使用图书馆而恨你?我们确实有点讨厌你,因为你没有在你的问题中包含错误。
  • 你说没有它我得到一个错误 - 什么错误?如果您不向我们提供报告的确切错误,则很难知道出了什么问题。请将其添加到问题中。
  • 另外,因为你递归地调用你的函数,我猜你最终会用一个空字符串作为s 参数来调用它。您是否真的尝试过调试您的代码?这应该是你做的第一件事。
  • 你应该考虑使用调试器...
  • 抛开一切,查找递归下降表达式解析,或 Dijkstra Shunting-yard 算法。

标签: java string parsing math substring


【解决方案1】:

我很确定这至少是您的代码中的一个位置,您可以将长度为 0 的字符串传递给您的 format 函数:

c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
    if(c[i] == '+') {
        return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
    } else if(c[i] == '-') {
        return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
    }
}

如果输入字符串中没有 +- 值,(int i = c.length-1; i &gt;= 0; i--) 中的循环计数器将递减,直到其值为 0。 然后你打电话给format(s.substring(0, i))i = 0,所以我认为这是你将零长度/空字符串传递给function的地方。

请使用调试器并单步调试您的代码 - 它不仅会教您一项宝贵的技能,还可能会为您提供所需的答案。

【讨论】:

  • 感谢调试器的提示;)实际上我使用了一些 System.out.println();s 来查看程序在做什么......我还写了一个小记录器,它告诉我错误指的是最后一行和你告诉我的部分,但我不明白程序为什么这样做......不过谢谢 :)
猜你喜欢
  • 1970-01-01
  • 2023-03-19
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多