package com.coding.basic.stack.expr; import java.util.List; import java.util.Stack; public class InfixExpr { String expr = null; public InfixExpr(String expr) { this.expr = expr; } public float evaluate() { TokenParser tokenParser = new TokenParser(); List<Token> tokens = tokenParser.parse(expr); if (!check(tokens)){ throw new RuntimeException("illegal expression"); } Stack<Token> operatorStack = new Stack<Token>(); Stack<Token> numberStack = new Stack<Token>(); for (Token token : tokens){ if (token.isNumber()){ numberStack.push(token); } if (token.isOperator()){ if (operatorStack.isEmpty() || token.hasHigherPriority(operatorStack.peek())){ operatorStack.push(token); } else { popOneOperator(operatorStack, numberStack); if (operatorStack.isEmpty() || token.hasHigherPriority(operatorStack.peek())){ operatorStack.push(token); } else { popOneOperator(operatorStack, numberStack); operatorStack.push(token); } } } } while (!operatorStack.isEmpty()){ popOneOperator(operatorStack, numberStack); } return Float.valueOf(numberStack.pop().toString()); } private void popOneOperator(Stack<Token> operatorStack, Stack<Token> numberStack){ Token operator = operatorStack.pop(); Token num1 = numberStack.pop(); Token num2 = numberStack.pop(); float res = evaluateTwo(num2, num1, operator); numberStack.push(new Token(Token.NUMBER, String.valueOf(res))); } private float evaluateTwo(Token num1, Token num2, Token o){ Float s1 = Float.valueOf(num1.toString()); Float s2 = Float.valueOf(num2.toString()); if (o.toString().equals("+")){ return s1 + s2; } else if (o.toString().equals("-")){ return s1 - s2; } else if (o.toString().equals("*")){ return s1 * s2; } else if (o.toString().equals("/")){ return s1 / s2; } throw new RuntimeException("unsupported operator [" + o.toString() + "]"); } private boolean check(List<Token> tokens) { if (tokens == null || tokens.isEmpty()){ return false; } int i = 0; for (Token token : tokens){ if (token.isNumber()){ i++; if ( i != 1){ return false; } } if (token.isOperator()){ i--; if ( i != 0){ return false; } } } return i == 1; } }