Infix Expression Evaluator

 
  1. /**
  2.  * filename: InfixEvaluator.java
  3.  * package:  infix
  4.  * author:   Li Ma
  5.  * email:    nick.ma85@yahoo.com
  6.  * date:     Oct 3, 2008
  7.  * description: this class evaluates infix by converting infix to postfix
  8.  */
  9. package  infix;
  10. import  java.util.*;
  11. public   class  InfixEvaluator {
  12.          /** the stack stores operators */
  13.          private  Stack<Character> operatorStack;
  14.         
  15.          /** the stack stores operands */
  16.          private  Stack<Integer> operandStack;
  17.         
  18.          /** each operator(char) has a integer value of priority */
  19.          private   static   final  Map<Character, Integer> OPERATORS;
  20.         
  21.          /** postfix exp converted from infix exp */
  22.          private  StringBuilder postfix;
  23.         
  24.          /** the infix exp */
  25.          private  String infix;
  26.         
  27.          static  {
  28.                  // initialize the static field
  29.                 OPERATORS =  new  HashMap<Character, Integer>();
  30.                 OPERATORS.put( '+'1 );
  31.                 OPERATORS.put( '-'1 );
  32.                 OPERATORS.put( '*'2 );
  33.                 OPERATORS.put( '/'2 );
  34.         }
  35.         
  36.          /**
  37.          * description: the default constructor
  38.          */
  39.          public  InfixEvaluator() {
  40.                  // TODO Auto-generated constructor stub
  41.                 operatorStack =  new  Stack<Character>();
  42.                 operandStack =  new  Stack<Integer>();
  43.                 
  44.                 infix =  null ;
  45.                 postfix =  new  StringBuilder();
  46.         }
  47.          /**
  48.          * description: the constructor with fields
  49.          * @param infixStr - the infix string
  50.          */
  51.          public  InfixEvaluator(String infixStr) {
  52.                  this ();
  53.                  this .infix = infixStr;
  54.         }
  55.          /**
  56.          * description: convert a string from infix to postfix
  57.          * @throws SyntaxErrorException
  58.          */
  59.          private   void  convertInfixToPostfix()  throws  SyntaxErrorException {
  60.                 StringTokenizer infixTokens =  new  StringTokenizer(infix);
  61.                  try  {
  62.                          while (infixTokens.hasMoreTokens()) {
  63.                                 String next = infixTokens.nextToken();
  64.                                  char  firstChar = next.charAt( 0 );
  65.                                  // determine whether it is operand
  66.                                  if (Character.isJavaIdentifierStart(firstChar)
  67.                                                 || Character.isDigit(firstChar)) {
  68.                                         postfix.append(next);
  69.                                         postfix.append( " " );
  70.                                 }  else   if (isOperator(firstChar)) {
  71.                                          // it is an operator
  72.                                         processOperator(firstChar);
  73.                                 }  else  {
  74.                                          throw   new  SyntaxErrorException( "Unexpected Character Encountered: "  + firstChar);
  75.                                 }
  76.                         }
  77.                         
  78.                          // pop any remaining operators and append them to postfix
  79.                          while (!operatorStack.empty()) {
  80.                                 Character op = operatorStack.pop();
  81.                                 postfix.append(op);
  82.                                 postfix.append( " " );
  83.                         }
  84.                 }  catch (EmptyStackException e) {
  85.                          throw   new  SyntaxErrorException( "Syntax error: the stack is empty" );
  86.                 }
  87.         }
  88.         
  89.          /**
  90.          * description: process operators, let them push or add to the postfix
  91.          * @param op - the character of the operator
  92.          */
  93.          private   void  processOperator( char  op) {
  94.                  if (operatorStack.empty()) {
  95.                         operatorStack.push( new  Character(op));
  96.                 }  else  {
  97.                          // peek the operator stack and let topOp be top
  98.                          char  topOp = operatorStack.peek().charValue();
  99.                          if (OPERATORS.get(op) > OPERATORS.get(topOp)) {
  100.                                 operatorStack.push( new  Character(op));
  101.                         }  else  {
  102.                                  // pop all stacked operators with equal or higher priority than op
  103.                                  while (!operatorStack.empty()
  104.                                                 && OPERATORS.get(op) <= OPERATORS.get(topOp)) {
  105.                                         operatorStack.pop();
  106.                                         postfix.append(topOp);
  107.                                         postfix.append( " " );
  108.                                          if (!operatorStack.empty()) {
  109.                                                 topOp = operatorStack.peek().charValue();
  110.                                         }
  111.                                 }
  112.                                 operatorStack.push( new  Character(op));
  113.                         }
  114.                 }
  115.         }
  116.         
  117.          /**
  118.          * description: determine whether the character is an operator
  119.          * @param ch - the character to be tested
  120.          * @return      true if ch is an operator
  121.          */
  122.          private   boolean  isOperator( char  ch) {
  123.                  return  OPERATORS.containsKey(ch);
  124.         }
  125.         
  126.          /**
  127.          * description: evaluate the current operation, poping the two operands off 
  128.          * the operand stack and applying the operator.
  129.          * @param op - a character representing the operator
  130.          * @return the result of applying the operator
  131.          */
  132.          private   int  evalOp( char  op) {
  133.                  // pop the two operands off the stack
  134.                  int  rhs = operandStack.pop();
  135.                  int  lhs = operandStack.pop();
  136.                  int  result =  0 ;
  137.                 
  138.                  // evaluate the operator
  139.                  switch (op) {
  140.                  case   '+' :
  141.                         result = lhs + rhs;
  142.                          break ;
  143.                  case   '-' :
  144.                         result = lhs - rhs;
  145.                          break ;
  146.                  case   '*' :
  147.                         result = lhs * rhs;
  148.                          break ;
  149.                  case   '/' :
  150.                         result = lhs / rhs;
  151.                          break ;
  152.                 }
  153.                  return  result;
  154.         }
  155.         
  156.          /**
  157.          * description: evaluate the whole infix expression
  158.          * @return      the value of the infix expression
  159.          * @throws SyntaxErrorException
  160.          */
  161.          public   int  eval()  throws  SyntaxErrorException {
  162.                  // translate the infix to postfix
  163.                  this .convertInfixToPostfix();
  164.                 
  165.                  // process each token
  166.                 StringTokenizer tokens =  new  StringTokenizer( this .postfix.toString());
  167.                  try  {
  168.                          while (tokens.hasMoreTokens()) {
  169.                                 String next = tokens.nextToken();
  170.                                 
  171.                                  if (Character.isDigit(next.charAt( 0 ))) {
  172.                                          int  value = Integer.parseInt(next);
  173.                                         
  174.                                          // push value onto operand stack
  175.                                         operandStack.push(value);
  176.                                 }  else   if (isOperator(next.charAt( 0 ))) {
  177.                                          // it is an operator
  178.                                          // evaluate the operator
  179.                                          int  result = evalOp(next.charAt( 0 ));
  180.                                         operandStack.push(result);
  181.                                 }  else  {
  182.                                          throw   new  SyntaxErrorException( "Invalid character encountered" );
  183.                                 }
  184.                         }
  185.                         
  186.                          // no more tokens, pop result from operand stack
  187.                          int  answer = operandStack.pop();
  188.                          if (operandStack.empty()) {
  189.                                  return  answer;
  190.                         }  else  {
  191.                                  // indicate syntax error
  192.                                  throw   new  SyntaxErrorException( "Stack should be empty" );
  193.                         }
  194.                 }  catch (EmptyStackException e) {
  195.                          throw   new  SyntaxErrorException( "the stack is empty" );
  196.                 }
  197.         }
  198. }
  199. /**
  200.  * filename: SyntaxErrorException.java
  201.  * package:  infix
  202.  * author:   Li Ma
  203.  * email:    nick.ma85@yahoo.com
  204.  * date:     Oct 3, 2008
  205.  * description: this exception shows a syntax error.
  206.  */
  207. package  infix;
  208. public   class  SyntaxErrorException  extends  Exception {
  209.          private   static   final   long  serialVersionUID = 1L;
  210.          public  SyntaxErrorException( final  String message) {
  211.                  super (message);
  212.         }
  213. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值