package com.aaront.exercise.basic.expr;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class InfixExpr {
private String expr = null;
private Map<Character, Integer> map = new HashMap<>(4);
public InfixExpr(String expr) {
this.expr = expr;
this.map.put('+', 1);
this.map.put('-', 1);
this.map.put('*', 2);
this.map.put('/', 2);
this.map.put('#', 0);
}
public float evaluate() {
Stack<Double> operands = new Stack<>();
// 要保证操作符栈中的操作符是按照操作符优先级递增的(不能相等)
Stack<Character> operators = new Stack<>();
operators.push('#');
for (int i = 0, len = expr.length(); i < len; i++) {
char c = expr.charAt(i);
Integer level = map.get(c);
if (c == '+' || c == '-' || c == '*' || c == '/') {
Character operator = operators.peek();
Integer value = map.get(operator);
while (level <= value) {
Double operand2 = operands.pop();
Double operand1 = operands.pop();
Double result = calc(operators.pop(), operand1, operand2);
operands.push(result);
operator = operators.peek();
value = map.get(operator);
}
operators.push(c);
} else {
int j = i;
for (; j < len && expr.charAt(j) >= '0' && expr.charAt(j) <= '9'; j++) ;
operands.push(Double.parseDouble(expr.substring(i, j)));
i = j - 1;
}
}
while (operators.size() != 1) {
Double operand2 = operands.pop();
Double operand1 = operands.pop();
Double result = calc(operators.pop(), operand1, operand2);
operands.push(result);
}
return operands.pop().floatValue();
}
private Double calc(Character operator, Double operand1, Double operand2) {
switch (operator) {
case '+':
return operand1 + operand2;
case '-':
return operand1 - operand2;
case '*':
return operand1 * operand2;
case '/':
return operand1 / operand2;
default:
throw new IllegalArgumentException("不支持的运算符");
}
}
}