2015-10-15 96 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