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); } }
一個簡單的公式計算,有須要的能夠參考一下java