DSA using Java - Parsing Expressions


Advertisements

Ordinary airthmetic expressions like 2*(3*4) are easier for human mind to parse but for an algorithm it would be pretty difficult to parse such an expression. To ease this difficulty, an airthmetic expression can be parsed by an algorithm using a two step approach.

  • Transform the provided arithmetic expression to postfix notation.

  • Evaluate the postfix notation.

Infix Notation

Normal airthmetic expression follows Infix Notation in which operator is in between the operands. For example A+B here A is first operand, B is second operand and + is the operator acting on the two operands.

Postfix Notation

Postfix notation varies from normal arithmetic expression or infix notation in a way that the operator follows the operands. For example, consider the following examples

Sr.No Infix Notation Postfix Notation
1A+BAB+
2(A+B)*CAB+C*
3A*(B+C)ABC+*
4A/B+C/DAB/CD/+
5(A+B)*(C+D)AB+CD+*
6((A+B)*C)-DAB+C*D-

Infix to PostFix Conversion

Before looking into the way to translate Infix to postfix notation, we need to consider following basics of infix expression evaluation.

  • Evaluation of the infix expression starts from left to right.

  • Keep precedence in mind, for example * has higher precedence over +. For example

    • 2+3*4 = 2+12.

    • 2+3*4 = 14.

  • Override precedence using brackets, For example

    • (2+3)*4 = 5*4.

    • (2+3)*4= 20.

Now let us transform a simple infix expression A+B*C into a postfix expression manually.

Step Character read Infix Expressed parsed so far Postfix expression developed so far Remarks
1AAA
2+A+A
3BA+BAB
4*A+B*AB+ can not be copied as * has higher precedence.
5CA+B*CABC
6A+B*CABC*copy * as two operands are there B and C
7A+B*CABC*+copy + as two operands are there BC and A

Now let us transform the above infix expression A+B*C into a postfix expression using stack.

Step Character read Infix Expressed parsed so far Postfix expression developed so farStack Contents Remarks
1AAA
2+A+A+push + operator in a stack.
3BA+BAB+
4*A+B*AB+*Precedence of operator * is higher than +. push * operator in the stack. Otherwise, + would pop up.
5CA+B*CABC+*
6A+B*CABC*+No more operand, pop the * operator.
7A+B*CABC*+Pop the + operator.

Now let us see another example, by transforming infix expression A*(B+C) into a postfix expression using stack.

StepCharacter readInfix Expressed parsed so farPostfix expression developed so farStack ContentsRemarks
1AAA
2*A*A*push * operator in a stack.
3(A*(A*(push ( in the stack.
4BA*(BAB*(
5+A*(B+AB*(+push + in the stack.
6CA*(B+CABC*(+
7)A*(B+C)ABC+*(Pop the + operator.
8A*(B+C)ABC+*Pop the ( operator.
9A*(B+C)ABC+*Pop the rest of the operator(s).

Demo program

Now we'll demonstrate the use of stack to convert infix expression to postfix expression and then evaluate the postfix expression.

Stack.java
package com.tutorialspoint.expression;

public class Stack {

   private int size;           
   private int[] intArray;     
   private int top;            

   //Constructor
   public Stack(int size){
      this.size = size;           
      intArray = new int[size];   
      top = -1;                   
   }

   //push item on the top of the stack
   public void push(int data) {
      if(!isFull()){
         //increment top by 1 and insert data
         intArray[++top] = data;
      }else{
         System.out.println("Cannot add data. Stack is full.");
      }      
   }

   //pop item from the top of the stack
   public int pop() {
      //retrieve data and decrement the top by 1
      return intArray[top--];        
   }

   //view the data at top of the stack
   public int peek() {       
      //retrieve data from the top
      return intArray[top];
   }

   //return true if stack is full
   public boolean isFull(){
      return (top == size-1);
   }

   //return true if stack is empty
   public boolean isEmpty(){
      return (top == -1);
   }
}

InfixToPostFix.java

package com.tutorialspoint.expression;

public class InfixToPostfix {
   private Stack stack;
   private String input = "";
   private String output = "";

   public InfixToPostfix(String input){
      this.input = input;
      stack = new Stack(input.length());
   }

   public String translate(){
      for(int i=0;i<input.length();i++){
         char ch = input.charAt(i);
            switch(ch){
               case '+':
               case '-':
                  gotOperator(ch, 1);
                  break;
               case '*':
               case '/':
                  gotOperator(ch, 2);
                  break;
               case '(':
                  stack.push(ch);
                  break;
               case ')':
                  gotParenthesis(ch);
                  break;
               default:
                  output = output+ch;            
                  break;
          }
      }

      while(!stack.isEmpty()){
         output = output + (char)stack.pop();
      }       

      return output;
   }   

      //got operator from input
      public void gotOperator(char operator, int precedence){
      while(!stack.isEmpty()){
         char prevOperator = (char)stack.pop();
         if(prevOperator == '('){
            stack.push(prevOperator);
            break;
         }else{
            int precedence1;
            if(prevOperator == '+' || prevOperator == '-'){
               precedence1 = 1;
            }else{
               precedence1 = 2;
            }

            if(precedence1 < precedence){
               stack.push(Character.getNumericValue(prevOperator));
               break;                        
            }else{
               output = output + prevOperator;
            }                
         }   
      }
      stack.push(operator);
   }

   //got operator from input
   public void gotParenthesis(char parenthesis){
      while(!stack.isEmpty()){
         char ch = (char)stack.pop();
         if(ch == '('){                
            break;
         }else{
            output = output + ch;               
         }   
      }        
   } 
}

PostFixParser.java

package com.tutorialspoint.expression;

public class PostFixParser {
private Stack stack;
private String input;

public PostFixParser(String postfixExpression){
   input = postfixExpression;
   stack = new Stack(input.length());
}

   public int evaluate(){
      char ch;
      int firstOperand;
      int secondOperand;
      int tempResult;

      for(int i=0;i<input.length();i++){
         ch = input.charAt(i);

         if(ch >= '0' && ch <= '9'){
            stack.push(Character.getNumericValue(ch));
         }else{
            firstOperand = stack.pop();
            secondOperand = stack.pop();
            switch(ch){
               case '+':
                  tempResult = firstOperand + secondOperand;
                  break;
               case '-':
                  tempResult = firstOperand - secondOperand;
                  break;
               case '*':
                  tempResult = firstOperand * secondOperand;
                  break;
               case '/':
                  tempResult = firstOperand / secondOperand;
                  break;   
               default:
                  tempResult = 0;
            }
            stack.push(tempResult);
         }
      }
      return stack.pop();
   }       
}

PostFixDemo.java

package com.tutorialspoint.expression;

public class PostFixDemo {
   public static void main(String args[]){
      String input = "1*(2+3)";
      InfixToPostfix translator = new InfixToPostfix(input);
      String output = translator.translate();
      System.out.println("Infix expression is: " + input);
      System.out.println("Postfix expression is: " + output);

      PostFixParser parser = new PostFixParser(output);
      System.out.println("Result is: " + parser.evaluate());
   }
}

If we compile and run the above program then it would produce following result −

Infix expression is: 1*(2+3)
Postfix expression is: 123+*
Result is: 5
Advertisements