Infix to Postfix conversion in Java

Posted on

Problem

I have written an infix-to-postfix program that I would like reviewed and with a few suggestions on improving it, such as a more modularized approach.

package basicstrut;

import java.util.Stack;

public class Infix {

    private String infixStr;

    private Stack<Character> oprStack;

    public Infix(String infixStr){
        oprStack = new Stack<Character>();
        this.infixStr = infixStr;
    }

    public String toPostFix(){
        StringBuffer buf = new StringBuffer(infixStr.length());

        for(int i=0;i<infixStr.length();i++){
            char str = (infixStr.charAt(i));            
            if(valueOfOpr(str) == 0){
                buf.append(str);

                if(i != infixStr.length()-1 && !oprStack.isEmpty()){
                    char nextChar = (infixStr.charAt(i+1));
                    char opStack = oprStack.peek();

                    int compare =  compareOperators (opStack,nextChar); 

                    if(compare >0 && valueOfOpr(opStack) != 5) {
                        opStack = oprStack.pop();
                        buf.append(opStack);
                    }
                }               
            }   

            if(i == infixStr.length()-1){
                if(valueOfOpr(str) > 0 && valueOfOpr(str) != 6) throw new RuntimeException("Invalid Expression");
                while(!oprStack.isEmpty()){
                    char temp = oprStack.pop();
                    if(valueOfOpr(temp) != 5)buf.append(temp);
                }
            }else if (valueOfOpr(str) > 0){

                if(oprStack.isEmpty()) {
                    oprStack.push(str);
                }else{ 

                    if(valueOfOpr(str) == 6){
                        while(!oprStack.isEmpty()){
                            char temp = oprStack.pop();
                            if(valueOfOpr(temp) != 5)buf.append(temp);
                        }                   
                    }else{
                        char opStack = oprStack.pop();
                        int compare =  compareOperators (opStack,str);  

                        if(compare >0) {
                            oprStack.push(str);oprStack.push(opStack);                  
                        }else{
                            oprStack.push(opStack);oprStack.push(str);
                        }   
                    }
                }                   
            }



        }

        return buf.toString();
    }


    public int compareOperators(char op1 , char op2){       
        return valueOfOpr( op1) - valueOfOpr( op2) ;
    }


    public int valueOfOpr(char op){
        int value = 0;

        switch (op) {
        case '*':
            value = 4;
            break;
        case '/':
            value = 3;
            break;
        case '+':
            value = 2;
            break;          
        case '-':
            value = 1;
            break;  
        case '[':           
        case ']':
        case '(':       
            value = 5;  
            break;
        case ')':
            value = 6;  
            break;          
        default:
            break;
        }

        return value;
    }



    public static void main(String[] args) {
        Infix i = new Infix("A+B");
/*      System.out.println("A+B -->"+i.toPostFix());
        i = new Infix("A+B-C");
        System.out.println("A+B-C -->"+i.toPostFix());

        i = new Infix("A+B*C");
        System.out.println("A+B*C -->"+i.toPostFix());
        i = new Infix("A*B+C");
        System.out.println("A*B+C -->"+ i.toPostFix());     
        i = new Infix("A/B+C");
        System.out.println("A/B+C -->"+i.toPostFix());
        i = new Infix("A+B/C");
        System.out.println("A+B/C -->"+ i.toPostFix());
        */
        i = new Infix("A*(B+C)");
        System.out.println("A*(B+C) -->"+ i.toPostFix());

        i = new Infix("A*(B+C)*(D+E)");
        System.out.println("A*(B+C)*(D+E) -->"+ i.toPostFix());

        i = new Infix("A*(B+C)-D/(E+F)");
        System.out.println("A*(B+C)-D/(E+F) -->"+ i.toPostFix());       

        i = new Infix("A*(B+C)-D/(E+F)*G+H");
        System.out.println("A*(B+C)-D/(E+F)*G+H -->"+ i.toPostFix());

        i = new Infix("(A*B*(C+D))");
        System.out.println("(A*B*(C+D)) -->"+ i.toPostFix());

        i = new Infix("(A*B*(C+D)*E+F)");
        System.out.println("(A*B*(C+D)*E+F) -->"+ i.toPostFix());

    }
}

Solution

One small thing you can do is improve the readability of things like

valueOfOpr(opStack) != 5

by making an Operator enum like so (notice I took the liberty of re-ordering the square brackets, correct me if I’m wrong):

public static enum Operator {
    NOT_AN_OPERATOR(0, ""),
    SUBTRACTION(1, "-"),
    ADDITION(2, "+"),
    DIVISION(3, "/"),
    MULTIPLICATION(4, "*"),
    OPEN_BRACKET(5, "[("),
    CLOSE_BRACKET(6, "])");

    private final int precedence;
    private final String symbol;

    private Operator(int precedence, String symbol) {
        this.precedence = precedence;
        this.symbol = symbol;
    }

    public int getPrecedence() {
        return precedence;
    }

    public static boolean isOperator(char symbol, Operator operator) {
        return operator.symbol.indexOf(symbol) != -1;
    }
}

That way,

valueOfOpr(str) == 0
valueOfOpr(opStack) != 5

would become

!Operator.isOperator(str, Operator.NOT_AN_OPERATOR);
!Operator.isOperator(opStack, Operator.OPEN_BRACKET);

etc.

Leave a Reply

Your email address will not be published. Required fields are marked *