2015-10-15 89 views
1

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

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; 

} 
+0

您能更清楚地了解您的问题吗? –

+1

此代码评估一个String表达式。它适用于诸如“3 * 4 + 5”之类的字符串,但不适用于诸如“-3 * 4 + 5”之类的字符串,因为负号被视为减法运算符。这就是我需要修复的问题 –

+0

把它全部扔掉,查找'递归下降表达式解析器'或者Dijkstra调车码算法。你永远不会从这里到达那里。 – EJP

回答

0

一个解决办法是永远不要“减”,只需添加负数(如果你需要减去的东西,乘以-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 
    } 
} 
+0

因此,无论何时遇到'-',我都需要用它的负值替换字符串中的下一项? –

+0

视情况而定。除非你想设置另一个值来表示一个负数,否则你想假装你不能减去数字,你所能做的只是添加,多重和除法。我输入了一些伪代码,可能会解释我说的背后的逻辑,但是你需要检查是否有什么东西在附近 - 知道该如何处理它。 –

+0

我喜欢考虑它的一个好方法是尽可能使数学变得简单。如果你有-3 * 4 + 5-9,你可以做一些像1 * -3 * 4 + -9这样的编译而不会出错。总是在左边有一个操作员 - 它会工作。 –

0

第一个要点是,字符串可以被解析,即使它包含减号( “ - ”)漂浮

所以,检查

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 =='/'; 
} 

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

最后一点是,这个递归算法是相当天真的,当括号出现时,您将需要更复杂的东西。 您可以在这里找到关于高级算法的信息: http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html