【问题标题】:Evaluate code, differentiating between minus and negative?评估代码,区分负数和负数?
【发布时间】:2015-10-15 21:39:30
【问题描述】:

我正在评估一个表达式,但在输入负数时遇到了麻烦。由于我的代码结构,以及减法运算符和负号是同一个字符的事实,我的代码不适用于负数。有没有办法解决这个问题?

private float evalNoPB(String s) {

    float tempAns = 0;
    if (s.contains("*") == false && s.contains("/") == false && s.contains("+") == false && s.contains("-") == false) {
        return Float.parseFloat(s);
    }

    if (s.length() - 1 > 0) {
        int i;
        boolean foundPlusMinus = false;
        for (i = s.length() - 1; i > 0; i--) {
            if (s.charAt(i) == '+' || s.charAt(i) == '-') {
                System.out.println(i);
                foundPlusMinus = true;
                break; // keep value of i for substrings 
            }
            foundPlusMinus = false;
        }

        if (foundPlusMinus == false) { // for loop went through and did not find + or -
            for (i = s.length() - 1; i > 0; i--) {
                if (s.charAt(i) == '*' || s.charAt(i) == '/') {
                    System.out.println(i);
                    break; // keep value of i for substrings
                }
            }
        }

        String sub1 = s.substring(0, i);
        System.out.println(sub1);
        String sub2 = s.substring(i + 1, s.length());
        System.out.println(sub2);

        if (s.charAt(i) == '+') {
            tempAns = evalNoPB(sub1) + evalNoPB(sub2);
        } else if (s.charAt(i) == '-') {
            tempAns = evalNoPB(sub1) - evalNoPB(sub2);
        } else if (s.charAt(i) == '*') {
            tempAns = evalNoPB(sub1) * evalNoPB(sub2);
        } else if (s.charAt(i) == '/') {
            float divisorCheck = evalNoPB(sub2);
            if (divisorCheck != 0) {
                tempAns = evalNoPB(sub1) / evalNoPB(sub2);
            } else { // cannot divide by 0 
                throw new IllegalArgumentException("cannot divide by 0");
            }
        }
    }
    return tempAns;

}

【问题讨论】:

  • 你的问题能不能再清楚一点?!!!
  • 此代码计算字符串表达式。它适用于诸如3*4+5 之类的字符串,但不适用于诸如-3*4+5 之类的字符串,因为负号被视为减法运算符。这是我需要解决的问题
  • 扔掉它并查找“递归下降表达式解析器”或 Dijkstra Shutting-yard 算法。你永远不会从这里到达那里。

标签: java evaluate


【解决方案1】:

一种解决方法是永远不要“减去”,只需添加负数(如果您需要减去某些内容,请将其乘以 -1 并与另一个数字相加)。

伪代码:

if I come across a - with nothing on either side and not first in string {
add a + to the left of it
}
else {
if first in string {
     add 1* to left of it
}
do stuff that has to do with *, /, or +.
}
if i run across a + {
    check to see if - is to right of it
    if so {
        add together the values but with the value to right of - multiplied by -1
    }
    else {
         add together values
    }
}

【讨论】:

  • 所以每当我遇到- 时,我需要用负值替换字符串中的下一项?
  • 视情况而定。除非你想设置另一个值来表示一个负数,否则你想假装你不能减去数字,你所能做的就是加、乘和除。我输入了一些伪代码,可以解释我所说的背后的逻辑,但是您需要检查 - 符号周围的内容才能知道如何处理它。
  • 我喜欢的一个好方法是让它在数学上尽可能简单。如果你有 -3*4+5-9 你可以做类似 1*-3*4+-9 的事情来让它编译没有错误。 - 左侧总是有一个运算符,它会起作用。
【解决方案2】:

第一个说明是字符串即使包含减号(“-”)也可以解析为浮点数

所以检查

if (s.contains("*") == false && s.contains("/") == false && s.contains("+") == false && s.contains("-") == false) {
    return Float.parseFloat(s);
}

不太对。它会跳过像“-10”这样的字符串。相反,我会建议

try {
  return Float.parseFloat(s);
} catch (NumberFormatException e) {
  System.out.println(s + " cannot be parsed to float");
}

我还建议将此解析移到方法的末尾。

第二个评论是关于找出减号是否与减法或负数有关。 在简单的算术表达式中,您尝试解析连接到负数的减号要么停留在第一位(例如 -1+14),要么紧随其后(例如 17*-1) 所以你需要替换循环

for (i = s.length() - 1; i > 0; i--) {
        if (s.charAt(i) == '+' || s.charAt(i) == '-') {
            System.out.println(i);
            foundPlusMinus = true;
            break; // keep value of i for substrings 
        }
        foundPlusMinus = false;
 }

for (i = s.length() - 1; i >= 0; i--) {
     if (s.charAt(i) == '+' || s.charAt(i) == '-' && (i != 0 && !isSign(s.charAt(i - 1)))) {
          System.out.println(i);
          foundPlusMinus = true;
          break; // keep value of i for substrings
     }
     foundPlusMinus = false;
}

private boolean isSign(char c) {
    return c == '+' || c == '-' || c == '*' || c =='/';
}

请注意,现在 i 下降到 0 (i>=0),如果我们找到减号,我们会检查前一个字符(如果存在)不是符号。在这种情况下,它是减号。

最后一点是,这种递归算法非常幼稚,当括号出现时,您将需要更复杂的东西。 例如,您可以在此处找到有关高级算法的信息: http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html

【讨论】:

    【解决方案3】:

    不要使用负数。改用一元减号运算符。所以 -23 不是负数 -23 而是正数 23 作为“-”一元运算符的参数。

    【讨论】:

      猜你喜欢
      • 2014-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 2021-05-09
      • 1970-01-01
      • 2022-01-09
      • 2018-02-09
      • 1970-01-01
      相关资源
      最近更新 更多