2012-10-16 65 views
1

這是到目前爲止我的代碼:後綴計算器,如何處理連續3個數字?

public class PostfixCalculator { 

    private Stack<Float> stack; 
    private float result; 

    private Boolean isOperator (char op){ 
    boolean operator; 
    switch (op){ 
     case '+': 
     case '-': 
     case '*': 
     case '/': 
     case '^': 
      operator = true; 
      break; 
    default: 
     operator = false; 
     break;} 
    return operator; 
} 

private Boolean isFunction (String func){ 
    String[] functions = {"sin", "cos", "max"}; 
    for (int i=0; i<functions.length; i++){ 
     if (func.equals(functions[i])) 
      return true; } 
    return false; 
} 

private void computeOperator (float op1, float op2, char op){ 
    switch (op){ 
     case '+': 
      result = op1 + op2; 
      break; 
     case '-': 
      result = op1 - op2; 
      break; 
     case '/': 
      result = op1/op2; 
      break; 
     case '*': 
      result = op1 * op2; 
      break; 
     case '^': 
      result = (float) Math.pow(op1, op2); 
      break; 

     default: 
      break; 
    } 
} 

public float calculate(String expr) throws IllegalArgumentException { 
    result = 0; 
    String token; 
    Float makeit; 
    char operator; 
    float op1, op2, pushFloat; 
    StringTokenizer calc=new StringTokenizer(expr); 

    stack = new Stack<Float>(); 

    while (calc.hasNextToken()){ 
     token=calc.getNextToken(); 
     operator=token.charAt(0); 

     if (!(this.isOperator(operator))){ 
      if (this.isFunction(token)){ 
       if (token.equals("sin")){ 
        op1=stack.pop(); 
        result = (float) Math.sin(op1); 
        stack.push(result); 
       } 
       else if (token.equals("cos")){ 
        op1=stack.pop(); 
        result = (float) Math.cos(op1); 
        stack.push(result); 
       } 
       else if (token.equals("max")){ 
        op1=stack.pop(); 
        op2=stack.pop(); 
        result=Math.max(op1, op2); 
        stack.push(result); 
       } 

      } 
      else { 
       makeit = new Float(token); 
       pushFloat = makeit.floatValue(); 
       stack.push(pushFloat); 
      } 

     } 
     else { 
      op1 = stack.pop(); 
      op2 = stack.pop(); 
      computeOperator (op1, op2, operator); 
      stack.push(result); 


     } 
    } 
    return stack.pop(); 
} 

}

我想我有下來的基礎,但如何處理後綴的計算與連續三位數以上,像例如'2 3 4 * - '?任何幫助,將不勝感激。提前致謝!

+0

爲了保持一致性/可理解性,'result'應該是本地的,'computeOperator'應該返回一個你賦給'result'的值。 –

+0

並且有兩個功能 - computeMonadic和computeDiadic。在computeDiadic中處理max和你的「操作符」。將isOperator替換爲isMonadic或isDiadic。 (不需要使用charAt - 只需將所有運算符/函數名稱視爲字符串即可。) –

+0

如果想要使用charAt,可以使用'Operator'類或類似方法,併爲每個運算符/函數創建子類。構建一個Operator子類和索引的數組以查找您的操作。 (但這將是「額外的功勞」)。 –

回答

1

是的,一個堆棧。我們可以很容易地使用數組和計數器來實現一個簡單的堆棧 - 不需要使用花哨的類。

該數組的大小與您可以處理的最深層嵌套表達式(10個元素應該足以滿足幾乎所有「真實」問題)一樣大。

推動更新A [i]並增加i。流行音樂是遞減我和參考A [我]。 「8 9 +」是按下(8),按下(9),彈出頂部的兩個元素,添加它們,按下結果。請注意,操作符永遠不會被推送,只有操作數/結果。 '將會推(2),推(3),推(4),彈出頂部2,乘,推結果,彈出2,減1,推結果。

「7 6 + cos」將被按下(7),按下(6),彈出兩個按鈕,添加按下結果,彈出一個按鈕,執行「cos」,按下結果。

如果您需要彈出某個元素並且計數器爲零(例如,「7 +」 - 您想要彈出兩次但只能彈出一次),則會出錯。如果用戶表示「已完成」並且堆棧中有多個元素,那麼也會出現錯誤。

始終「顯示」您的頂部元素,因爲這是最後推送的值或結果。

+0

感謝您的幫助。我已經實現了一個堆棧,並且按照我的想法推動它,但出於某種原因2 3 4 *正在做4-(2 * 3)。在檢查了它是一個函數還是操作符之後,我將該令牌插入堆棧,但是我是否跳過了某些東西,或者以某種方式錯誤地執行了它? – Akaraka

+0

@Akaraka - 這聽起來像(你沒有試圖破譯你的代碼),你正在將操作符(或函數)推入堆棧。有了這個方案,你永遠不會推動運營商/功能 - 只有價值。(並且,如另一篇文章所示,您對待操作符和函數完全一樣。) –

+0

我查看了我的代碼,我不認爲我將操作符/函數推入堆棧,因爲我檢查它是否是一個函數或操作符在推入堆棧之前首先...我可以忽略某處的某個東西嗎?謝謝您的幫助! – Akaraka

1

對於像這樣的計算器,您應該使用堆棧。每個數字都是一個推動,每個操作都有相應的操作。

st = [] 
while input: 
    if isanumber(input.next()): st.push(input.consume()) 
    else: #its an operator 
    #note this may be wrong for operators that have a specific order 
    if(input.next() == "+"): 
     stack.push(stack.pop() + stack.pop()) 
    # more operations 
    input.consume() 
print(st) 

而這將是粗略的python來做到這一點,在這種情況下,我在做出決定前向前看一個單一的標記。

編輯:

也許應該讀你的代碼發佈前,無論如何你必須推後計算的數字,還試圖簡化你的代碼只有「功能」和「數字」使執行兩種功能。正則表達式對於這類事情也很有用,例如http://www.cplusplus.com/reference/std/regex/