2013-04-10 33 views
1

忍受着我,我現在有點油炸把這一切弄到一起,但我在最後一段時間。我用java製作了一個計算器,它用一箇中綴方程,然後將其更改爲後綴。它也需要變量!我做到了,所以我的後綴包含來自中綴的負數。這看起來就像這樣:在堆疊計算器中計算底片

infix: 1+-2*(4/2) 
postfix: 12_42/*+ 

所以很明顯,我得到它的工作,其中底片的後綴是'_'。酷耶?好吧,但是現在我得讓我的計算器讀取它們,並且我只是對它在堆棧上的位置以及我所做的工作做了大腦放屁,而沒有爲所有形式的操作數制定條件。這是我有:

import java.util.Stack; 

/** 
* 
* @author rtibbetts268 
*/ 
public class InfixToPostfix 
{ 
     /** 
     * Operators in reverse order of precedence. 
     */ 
    private static final String operators = "-+/*_"; 
    private static final String operands = "x"; 

    /*public int evalInfix(String infix) 
    { 
     return evaluatePostfix(convert2Postfix(infix)); 
    }*/ 

    public String xToValue(String postfixExpr, String x) 
    { 
     char[] chars = postfixExpr.toCharArray(); 
     StringBuilder newPostfixExpr = new StringBuilder(); 

     for (char c : chars) 
     { 
      if (c == 'x') 
      { 
       newPostfixExpr.append(x); 
      } 
      else 
      { 
       newPostfixExpr.append(c); 
      } 
     } 
     return newPostfixExpr.toString(); 
    } 

    public String convert2Postfix(String infixExpr) 
    { 
     char[] chars = infixExpr.toCharArray(); 
     StringBuilder in = new StringBuilder(infixExpr.length()); 

     for (int i = 0; i<chars.length; i++) 
     { 
      if (infixExpr.charAt(i) == '-') 
      { 
       if (i == 0) 
       { 
       in.append('_'); 
       } 
       else if(isOperand(infixExpr.charAt(i + 1))) 
       { 
        if (i != infixExpr.length()) 
        { 
        if (isOperator(infixExpr.charAt(i-1))) 
         in.append('_'); 
        } 
        else 
        { 
         in.append(infixExpr.charAt(i)); 
        } 
       } 
       else 
       { 
        in.append(infixExpr.charAt(i)); 
       } 
      } 
      else 
      { 
       in.append(infixExpr.charAt(i)); 
      } 
     } 

     chars = in.toString().toCharArray(); 
     Stack<Character> stack = new Stack<Character>(); 
     StringBuilder out = new StringBuilder(in.toString().length()); 

     for (char c : chars) 
     { 
      if (isOperator(c)) 
      { 
       while (!stack.isEmpty() && stack.peek() != '(') 
       { 
        if (operatorGreaterOrEqual(stack.peek(), c)) 
        { 
         out.append(stack.pop()); 
        } 
        else 
        { 
         break; 
        } 
       } 
       stack.push(c); 
      } 
      else if (c == '(') 
      { 
       stack.push(c); 
      } 
      else if (c == ')') 
      { 
       while (!stack.isEmpty() && stack.peek() != '(') 
       { 
        out.append(stack.pop()); 
       } 
       if (!stack.isEmpty()) 
       { 
        stack.pop(); 
       } 
      } 
      else if (isOperand(c)) 
      { 
       out.append(c); 
      } 
     } 
     while (!stack.empty()) 
     { 
      out.append(stack.pop()); 
     } 
     return out.toString(); 
    } 

    public int evaluatePostfix(String postfixExpr)//YBEYFCNUNKJKDV IT'S RIGHT HERE!!! 
    { 
     char[] chars = postfixExpr.toCharArray(); 
     Stack<Integer> stack = new Stack<Integer>(); 
     for (char c : chars) 
     { 
      if (isOperand(c)) 
      { 
       stack.push(c - '0'); // convert char to int val 
      } 
      else if (isOperator(c)) 
      { 
       int op1 = stack.pop(); 
       int op2 = stack.pop(); 
       int result; 
       switch (c) { 
        case '_': 
         result = op1 * -1; 
         //stack.push(result); 
         //break; 
        case '*': 
         result = op1 * op2; 
         stack.push(result); 
         break; 
        case '/': 
         result = op2/op1; 
         stack.push(result); 
         break; 
        case '+': 
         result = op1 + op2; 
         stack.push(result); 
         break; 
        case '-': 
         result = op2 - op1; 
         stack.push(result); 
         break; 
       } 
      } 
     } 
     return stack.pop(); 
    } 

    private int getPrecedence(char operator) 
    { 
     int ret = 0; 
     if (operator == '-' || operator == '+') 
     { 
      ret = 1; 
     } 
     else if (operator == '*' || operator == '/') 
     { 
      ret = 2; 
     } 
     if (operator == '_') 
     { 
      ret = 3; 
     } 
     return ret; 
    } 

    private boolean operatorGreaterOrEqual(char op1, char op2) 
    { 
     return getPrecedence(op1) >= getPrecedence(op2); 
    } 

    private boolean isOperator(char val) 
    { 
     return operators.indexOf(val) >= 0; 
    } 

    private boolean isOperand(char val) 
    { 
     return operands.indexOf(val) >= 0; 
    } 

} 

我會張貼少,但它都傾向於工作一致,所以我會解釋。仔細查看名爲evaluatePostfix()的方法(這是來自頂端的第三個方法)。

這是類可以採用後綴表達式的位置,例如上面提到的那個表達式並計算它。它用所有正整數來計算一個表達式,但是當我試圖實現它來在實際運行任何數學運算之前將其數字更改爲負數時,它就是kaputt。

任何人都可以幫助我解決這個具體的方法,所以它的工作原理?我需要它來計算積極的負整數。

+0

後綴堆棧計算器非常簡單。在輸入流中有值時,按下它們。當您在輸入流中遇到操作符時,在頂層堆棧項目上執行它,移除這些項目,然後推送結果。 – 2013-04-11 00:24:32

+0

顯然你把'_'當作否定運算符,所以它彈出頂部項目,否定它,並推送結果。 – 2013-04-11 00:27:27

回答

2

基本上問題在於試圖從空棧中彈出'_'情況。你需要做的只是嘗試從棧中彈出'*/+ - '情況而不是'_'情況。

public int evaluatePostfix(String postfixExpr) 
{ 
    char[] chars = postfixExpr.toCharArray(); 
    Stack<Integer> stack = new Stack<Integer>(); 
    for (char c : chars) 
    { 
     if (isOperand(c)) 
     { 
      stack.push(c - '0'); // convert char to int val 
     } 
     else if (isOperator(c)) 
     { 
      int op1 = stack.pop(); 
      int op2; 
      int result; 
      switch (c) { 
       case '_': 
        result = op1 * -1; 
        stack.push(result); 
        break; 
       case '*': 
        op2 = stack.pop(); 
        result = op1 * op2; 
        stack.push(result); 
        break; 
       case '/': 
        op2 = stack.pop(); 
        result = op2/op1; 
        stack.push(result); 
        break; 
       case '+': 
        op2 = stack.pop(); 
        result = op1 + op2; 
        stack.push(result); 
        break; 
       case '-': 
        op2 = stack.pop(); 
        result = op2 - op1; 
        stack.push(result); 
        break; 
      } 
     } 
    } 
    return stack.pop(); 
}