package com.coding.basic.stack.expr;
import com.coding.basic.stack.Stack;
import java.util.Arrays;
public class InfixExpr {
String expr = null;
public InfixExpr(String expr) {
this.expr = expr;
}
public static void main(String[] args) {
String[] ss = new InfixExpr("3*20+12*5-40/2").getOperatorsAndNumbers("3*20+12*5-40/2");
System.out.println(Arrays.toString(ss));
}
/**
* 根据输入的表达式,计算结果
* 只支持 +、-、*、/,不支持括号
* 数值只支持整数
*
* @return 计算结果
*/
public float evaluate() {
if (expr == null) {
throw new NullPointerException("expr can't be null!");
}
Stack<String> operators = new Stack<>();
Stack<Number> nums = new Stack<>();
String[] operatorsAndNumbers = getOperatorsAndNumbers(expr);
for (int i = 0; i < operatorsAndNumbers.length; i++) {
String data = operatorsAndNumbers[i];
if ("+".equals(data) || "-".equals(data)) {
operators.push(data);
}
// "*" 的优先级最高,遇到 "*" 直接进行计算
else if ("*".equals(data)) {
nums.push(nums.pop().floatValue() * Integer.valueOf(operatorsAndNumbers[++i]));
}
// "/" 的优先级最高,遇到 "/" 直接进行计算
else if ("/".equals(data)) {
nums.push(nums.pop().floatValue() / Integer.valueOf(operatorsAndNumbers[++i]));
}
// 如果是数值,判断数值下一位的操作符,如果是 "+" 或 "-",
// 则优先级不高于堆栈中存储的操作符,取出堆栈中的进行计算
else {
if ((i + 1 < operatorsAndNumbers.length && !nums.isEmpty())
&&
("+".equals(operatorsAndNumbers[i + 1]) || "-".equals(operatorsAndNumbers[i + 1]))
) {
String operator = operators.pop();
float rightValue = Integer.valueOf(data);
float leftValue = nums.pop().floatValue();
if ("+".equals(operator)) {
nums.push(leftValue + rightValue);
} else {
nums.push(leftValue - rightValue);
}
} else {
try {
nums.push(Integer.valueOf(data));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("表达式不合法!");
}
}
}
}
if (!operators.isEmpty()) {
String operator = operators.pop();
float rightValue = nums.pop().floatValue();
float leftValue = nums.pop().floatValue();
if ("+".equals(operator)) {
nums.push(leftValue + rightValue);
} else {
nums.push(leftValue - rightValue);
}
}
return nums.pop().floatValue();
}
private String[] getOperatorsAndNumbers(String expr) {
String[] numberArray = expr.split("\\+|-|\\*|/");
String[] operatorsArray = expr.split("[0-9]+");
String[] operatorsAndNumbers = new String[operatorsArray.length + numberArray.length - 1];
for (int i = 1; i < operatorsArray.length; i++) {
operatorsAndNumbers[2 * i - 1] = operatorsArray[i];
}
for (int i = 0; i < numberArray.length; i++) {
operatorsAndNumbers[2 * i] = numberArray[i];
}
return operatorsAndNumbers;
}
}