共计 3663 个字符,预计需要花费 10 分钟才能阅读完成。
import java.math.BigDecimal;
import java.util.*;
/**
* 简略的公式计算工具,仅反对 +、-、*、/、()* @author ningyongli
* @date 2020-07-13
*/
public class CalculateUtils {private static final Map<String, Integer> PRIORITY_MAP = new HashMap<>();
private static final List<String> OPERATOR_LIST = new ArrayList<>();
static {PRIORITY_MAP.put("(", 0);
PRIORITY_MAP.put("+", 5);
PRIORITY_MAP.put("-", 5);
PRIORITY_MAP.put("*", 10);
PRIORITY_MAP.put("/", 10);
PRIORITY_MAP.put(")", 15);
OPERATOR_LIST.add("+");
OPERATOR_LIST.add("-");
OPERATOR_LIST.add("*");
OPERATOR_LIST.add("/");
OPERATOR_LIST.add("(");
OPERATOR_LIST.add(")");
}
/**
* 计算入口,除法计算小数位为 16 位
* @param data 数据
* @param express 公式
* @return BigDecimal 计算结果
*/
public static String execute(Map<String, String> data, String express) {express = express.replaceAll("\\s", "");
List<String> expressWordArr = split(express);
Stack<String> dataStack = new Stack<>();
Stack<String> operatorStact = new Stack<>();
for (String expressWord : expressWordArr) {if (!OPERATOR_LIST.contains(expressWord)) {dataStack.push(expressWord);
} else {if (operatorStact.isEmpty()) {operatorStact.push(expressWord);
} else {if ("(".equals(expressWord)) {operatorStact.push(expressWord);
} else if (")".equals(expressWord)) {
// 括号内计算;
operatorStact.push(expressWord);
dalRightBracket(dataStack, operatorStact, data);
} else {
// 加减乘除
calculate(dataStack, operatorStact, expressWord, data);
}
}
}
}
while (!operatorStact.empty()) {String operator = operatorStact.pop();
dal(dataStack, operator, data);
}
return data.get(dataStack.pop());
}
/**
* 解析关键词
* @param express 公式
* @return List<String> 拆分后的公式
*/
private static List<String> split(String express) {List<String> list = new ArrayList<>();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < express.length(); i++) {char c = express.charAt(i);
if (!OPERATOR_LIST.contains(String.valueOf(c))) {builder.append(c);
} else {list.add(builder.toString());
builder.delete(0, builder.length());
list.add(String.valueOf(c));
}
if (i == (express.length() - 1)) {if (builder.length() > 0) {list.add(builder.toString());
}
}
}
return list;
}
/**
* 括号内计算
* @param dataStack 数据栈
* @param operatorStact 操作栈
* @param s 操作符
* @param data 数据
*/
private static void calculate(Stack<String> dataStack, Stack<String> operatorStact, String s, Map<String, String> data) {String oldOp = operatorStact.peek();
int oldOpNum = PRIORITY_MAP.get(oldOp);
int currentNum = PRIORITY_MAP.get(s);
if (oldOpNum >= currentNum) {dal(dataStack, oldOp, data);
operatorStact.pop();
if (operatorStact.isEmpty()) {operatorStact.push(s);
} else {calculate(dataStack, operatorStact, s, data);
}
} else {operatorStact.push(s);
}
}
/**
* 括号内计算
* @param dataStack 数据栈
* @param operatorStact 操作栈
* @param data 数据
*/
private static void dalRightBracket(Stack<String> dataStack, Stack<String> operatorStact, Map<String, String> data) {while ( !operatorStact.empty() && ")".equals(operatorStact.peek())) {String rightBracket = operatorStact.pop();
String tempOp = operatorStact.peek();
if ("(".equals(tempOp)) {operatorStact.pop();
} else {dal(dataStack, tempOp, data);
operatorStact.pop();
operatorStact.push(rightBracket);
}
}
}
/**
* 根底计算
* @param dataStack 数据栈
* @param operator 操作符
* @param data 数据
*/
private static void dal(Stack<String> dataStack, String operator, Map<String, String> data) {String temp = dataStack.pop();
String oldTemp = dataStack.pop();
BigDecimal tempValue;
BigDecimal tempBigDecimal = new BigDecimal(data.get(temp));
BigDecimal oldTempBigDecimal = new BigDecimal(data.get(oldTemp));
switch (operator) {
case "+":
tempValue = oldTempBigDecimal.add(tempBigDecimal);
break;
case "-":
tempValue = oldTempBigDecimal.subtract(tempBigDecimal);
break;
case "*":
tempValue = oldTempBigDecimal.multiply(tempBigDecimal);
break;
case "/":
tempValue = oldTempBigDecimal.divide(tempBigDecimal, 16, BigDecimal.ROUND_HALF_UP);
break;
default:
throw new BaseRunTimeException("不反对的计算操作");
}
String uuid = String.valueOf(UUID.randomUUID());
data.put("tempValue-" + uuid, tempValue.toString());
dataStack.push("tempValue-" + uuid);
}
}
一个简略的公式计算,有须要的能够参考一下
正文完