package com.github.miniyk2012.coding2017.basic.stack.expr; import java.util.EmptyStackException; import java.util.LinkedList; import java.util.List; import java.util.Stack; public class InfixExpr { private String expr = null; enum Operator { PLUS("+", 1), SUB("-", 1), MUL("*", 2), DIV("/", 2); // 优先级越大,说明应该先算 private String value; private int priority; Operator(String value, int prioriy) { this.value = value; this.priority = prioriy; } public static Operator parseOperator(String value) { for (Operator c : Operator.values()) { if (c.value.equals(value)) { return c; } } throw new RuntimeException("运算符不存在"); } } public InfixExpr(String expr) { this.expr = expr; } private static Token<Float> evaluate(Token<Operator> operator, Token<Float> number1, Token<Float> number2) { float ret; switch (operator.value) { case PLUS: ret = number1.getValue() + number2.getValue(); break; case SUB: ret = number1.getValue() - number2.getValue(); break; case MUL: ret = number1.getValue() * number2.getValue(); break; case DIV: ret = number1.getValue() / number2.getValue(); break; default: throw new RuntimeException("运算符不存在"); } return new Token(ret, true); } public float evaluate() { List<Token> tokens= Token.parse(expr); Stack<Token<Float>> numberStack = new Stack<>(); Stack<Token<Operator>> operatorStack = new Stack<>(); for (Token t : tokens) { if (t.isNumber()) { numberStack.push(t); } else { if (operatorStack.isEmpty()) { operatorStack.push(t); } else { Token<Operator> preT = operatorStack.peek(); while (preT.value.priority >= ((Operator)t.value).priority) { Token number2 = numberStack.pop(); Token number1 = numberStack.pop(); operatorStack.pop(); numberStack.push(evaluate(preT, number1, number2)); try { preT = operatorStack.peek(); } catch (EmptyStackException e) { break; } } operatorStack.push(t); } } } while (!operatorStack.isEmpty()) { Token number2 = numberStack.pop(); Token number1 = numberStack.pop(); Token operator = operatorStack.pop(); numberStack.push(evaluate(operator, number1, number2)); } return numberStack.pop().getValue(); } private static class Token<T> { private boolean number; // 是数字/操作符 private T value; public boolean isNumber() { return number; } public T getValue() { return value; } public Token(T value, boolean number) { this.value = value; this.number = number; } public static List<Token> parse(String expr) { int i = 0; int size = expr.length(); String current; List<Token> tokens = new LinkedList<>(); String value = ""; while (i < size) { current = expr.substring(i,i+1); if (isOperator(current)) { tokens.add(new Token(Float.parseFloat(value), true)); value = ""; tokens.add(new Token(Operator.parseOperator(current), false)); } else { value += current; } i++; } tokens.add(new Token(Float.parseFloat(value), true)); return tokens; } private static boolean isOperator(String value) { for (Operator c : Operator.values()) { if (c.value.equals(value)) { return true; } } return false; } } public static void main(String[] args) { } }