Postfix Expression Evaluator

来源:互联网 发布:下载格式化工厂软件 编辑:程序博客网 时间:2024/05/16 07:22
 
  1. /**
  2.  * filename: PostfixEvaluator.java
  3.  * package:  
  4.  * author:   Li Ma
  5.  * email:    nick.ma85@yahoo.com
  6.  * date:     Oct 3, 2008 (created)
  7.  *                       Nov 2, 2008 (modified)
  8.  * description: this class evaluates postfix expression.
  9.  */
  10. import java.util.*;
  11. public class PostfixEvaluator {
  12.         
  13.         /** the stack stores operands */
  14.         private Stack<Integer> operandStack;
  15.         
  16.         /** each operator(char) has a integer value of priority */
  17.         private static final Map<Character, Integer> OPERATORS;
  18.         
  19.         /** postfix expression */
  20.         private String postfix;
  21.         
  22.         static {
  23.                 // initialize the static field
  24.                 OPERATORS = new HashMap<Character, Integer>();
  25.                 OPERATORS.put('+'1);
  26.                 OPERATORS.put('-'1);
  27.                 OPERATORS.put('*'2);
  28.                 OPERATORS.put('/'2);
  29.         }
  30.         
  31.         /**
  32.          * description: the constructor with fields
  33.          */
  34.         public PostfixEvaluator(String postfix) {
  35.                 // TODO Auto-generated constructor stub
  36.                 operandStack = new Stack<Integer>();
  37.                 this.postfix = postfix;
  38.         }
  39.         /**
  40.          * description: determine whether the character is an operator
  41.          * @param ch - the character to be tested
  42.          * @return      true if ch is an operator
  43.          */
  44.         private boolean isOperator(char ch) {
  45.                 return OPERATORS.containsKey(ch);
  46.         }
  47.         
  48.         /**
  49.          * description: evaluate the current operation, poping the two operands off 
  50.          * the operand stack and applying the operator.
  51.          * @param op - a character representing the operator
  52.          * @return the result of applying the operator
  53.          */
  54.         private int evalOp(char op) {
  55.                 // pop the two operands off the stack
  56.                 int rhs = operandStack.pop();
  57.                 int lhs = operandStack.pop();
  58.                 int result = 0;
  59.                 
  60.                 // evaluate the operator
  61.                 switch(op) {
  62.                 case '+':
  63.                         result = lhs + rhs;
  64.                         break;
  65.                 case '-':
  66.                         result = lhs - rhs;
  67.                         break;
  68.                 case '*':
  69.                         result = lhs * rhs;
  70.                         break;
  71.                 case '/':
  72.                         result = lhs / rhs;
  73.                         break;
  74.                 }
  75.                 return result;
  76.         }
  77.         
  78.         /**
  79.          * description: evaluate the whole infix expression
  80.          * @return      the value of the infix expression
  81.          * @throws SyntaxErrorException
  82.          */
  83.         public int eval() throws SyntaxErrorException {
  84.                 
  85.                 // process each token
  86.                 StringTokenizer tokens = new StringTokenizer(this.postfix);
  87.                 try {
  88.                         while(tokens.hasMoreTokens()) {
  89.                                 String next = tokens.nextToken();
  90.                                 
  91.                                 if(Character.isDigit(next.charAt(0))) {
  92.                                         int value = Integer.parseInt(next);
  93.                                         
  94.                                         // push value onto operand stack
  95.                                         operandStack.push(value);
  96.                                 } else if(isOperator(next.charAt(0))) {
  97.                                         // it is an operator
  98.                                         // evaluate the operator
  99.                                         int result = evalOp(next.charAt(0));
  100.                                         operandStack.push(result);
  101.                                 } else {
  102.                                         throw new SyntaxErrorException("Invalid character encountered");
  103.                                 }
  104.                         }
  105.                         
  106.                         // no more tokens, pop result from operand stack
  107.                         int answer = operandStack.pop();
  108.                         if(operandStack.empty()) {
  109.                                 return answer;
  110.                         } else {
  111.                                 // indicate syntax error
  112.                                 throw new SyntaxErrorException("Stack should be empty");
  113.                         }
  114.                 } catch(EmptyStackException e) {
  115.                         throw new SyntaxErrorException("the stack is empty");
  116.                 }
  117.         }
  118. }
  119. /**
  120.  * filename: SyntaxErrorException.java
  121.  * package:  
  122.  * author:   Li Ma
  123.  * email:    nick.ma85@yahoo.com
  124.  * date:     Oct 3, 2008
  125.  * description: this exception shows a syntax error.
  126.  */
  127. public class SyntaxErrorException extends Exception {
  128.         private static final long serialVersionUID = 1L;
  129.         public SyntaxErrorException(final String message) {
  130.                 super(message);
  131.         }
  132. }
原创粉丝点击