2015-10-14 132 views
-1

我编写了这个代码递归地评估一个表达式(我没有完成,只是按照括号和圆括号的方式工作),并且我刚完成了乘法/除法/加法/减法的递归。我得到一个StringOutOfBoundsException为String sub1 = s.substring(0,i);,有什么想法为什么?我放了一些打印语句来检查我的值,它从来没有作为一个字符串索引不可能的值,那么我的问题是什么?递归表达式评估?

public float evaluate() { 
    String s = expr; 
    float answer = 0; 

    //one single variable or just a number 
    if(s.contains("+") == false && s.contains("-") == false && s.contains("*") == false && s.contains("/") == false && s.contains("[") == false &&s.contains("]") == false && s.contains("(") == false && s.contains(")") == false){ 
     if(scalars.size() == 0){ 
      answer = Float.parseFloat(s); 
      return answer; 
     } 
     answer = this.scalars.get(0).value; 
     System.out.println("one var/number loop"); 
     return answer; 
    } 
    //no parentheses/brackets 
    if(s.contains("(") == false && s.contains(")") == false && s.contains("[") == false && s.contains("]") == false && (s.contains("+") == true || s.contains("-") == true || s.contains("*") == true || s.contains("/") == true)){ 
     answer = evalNoPB(s); 
     System.out.println("no parens loop"); 
     return answer; 
    } 
    //make compiler happy 
    System.out.println("no loop"); 
    return 0; 
    } 
    private float evalNoPB(String s){ 
     float tempAns = 0; 
    if(s.contains("(") == false && s.contains(")") == false && s.contains("[") == false && s.contains("]") == false){ 
     int i; 
     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 
      } 
     } if (i<0) { // 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); 
    String sub2 = s.substring(i+1, s.length()); 

    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; 
} 

测试

Enter the expression, or hit return to quit => 3*3 
1 (this is the i value) 
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String  
index out of range: -1 
at java.lang.String.substring(Unknown Source) 
at apps.Expression.evalNoPB(Expression.java:306) 
at apps.Expression.evalNoPB(Expression.java:314) 
at apps.Expression.evaluate(Expression.java:280) 
at apps.Evaluator.main(Evaluator.java:36) 
+1

_it从来没有作为一个值不可能的字符串索引_我不相信你。发布堆栈跟踪。 Post和MCVE。 –

+0

我添加了一个测试用例,你是什么意思的堆栈跟踪?对不起,我是新手 –

+0

该消息清楚地表明您使用了'-1'作为参数。 –

回答

0
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 
    } 
} 

在这个代码段变量最终成为-1并继续执行。 即使实际的设计应该改变,对于这一步,只需加入如果声明,声明将解决的情况。

if (i < 0) { // 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 
    } 
    } 
} 
if(i < 0) 
    return tempAns; 
String sub1 = s.substring(0, i); 

但是只有这种情况,您才会有其他问题。

+0

你如何建议我改变它?这个'if'语句总是会返回我初始化的tempAns到 –

+0

正如我所说的,你应该改变你的整体结构。如果我们试图解决所有问题并使其运行,所有的努力都是徒劳的。相反,您应该阅读**中缀**符号**前缀**或**后缀**符号转换。一旦你建立你的**前缀**,你的代码将更加结构化。你应该考虑改变你的代码**运算符优先级**如果你想要实际的方法。你似乎在** **和**分区**之前评估** + **和** - **运营商。 –

0

由String方法抛出,表明索引或者为负,或者超出字符串的大小越大。对于某些方法(如charAt方法),当索引等于字符串的大小时,也会引发此异常。

Here's an example: 

String s = "abc"; 
char c = s.charAt(3);