2015-10-14 234 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);