public static void main(String[] args) { // 支持括號 小數 負數 String statement = "-10/(4.5+5.5)*(-4-6+20)/-2"; // 10/(-2) 也行 System.out.println(calculate(statement)); } @SuppressWarnings("unchecked") private static double calculate(String statement){ Object[] result = filter(statement); // 運算數字 List<Double> numList = (List) result[0]; // 運算符 List<Character> symbolList = (List) result[1]; while (!symbolList.isEmpty()) { int index = symbolList.indexOf('('); if (index == -1) { // 沒有括號正常運算 realCalculate(numList, symbolList); } else { int right = symbolList.indexOf(')'); if (right == index + 1) { // 括號內的值都取完了,刪除括號 symbolList.remove(index); symbolList.remove(index); continue; } // 左右括號齊全 先算括號內的 if (right != -1) { List<Double> doubles = numList.subList(index, right); List<Character> subChars = symbolList.subList(index + 1, right); realCalculate(doubles, subChars); } } } return numList.get(0); } /** * @return 一個包含數字的列表和一個包含運算符的列表 */ private static Object[] filter(String statement) { // 形式 123,456,789 可能會有空字符串 StringBuilder nums = new StringBuilder(); // 符號列表 List<Character> symbolList = new LinkedList<>(); for (int i = 0; i < statement.length(); i++) { char c = statement.charAt(i); if (c == '-' && (i == 0 || statement.charAt(i - 1) == '(' || statement.charAt(i - 1) == '*' || statement.charAt(i - 1) == '/')) { nums.append(c).append(statement.charAt(i + 1)); i++; } else if (Character.isDigit(c) || c == '.') { nums.append(c); } else { symbolList.add(c); nums.append(','); } } String[] ss = nums.toString().split(","); List<Double> numList = new ArrayList<>(); for (String num : ss) { if (!num.isEmpty()) { numList.add(Double.parseDouble(num)); } } return new Object[]{numList, symbolList}; } private static void realCalculate(List<Double> numList, List<Character> symbolList) { while (!symbolList.isEmpty()) { int index = symbolList.indexOf('*'), tmp; double value = 0.0D; if (index != -1 && (tmp = symbolList.indexOf('/')) != -1) { // 同時出現 * / 從左至右運算 if (index < tmp) { value = numList.remove(index) * numList.remove(index); } else { index = tmp; value = numList.remove(index) / numList.remove(index); } } else if (index != -1) { value = numList.remove(index) * numList.remove(index); } else if ((index = symbolList.indexOf('/')) != -1) { value = numList.remove(index) / numList.remove(index); } else if ((index = symbolList.indexOf('+')) != -1 && (tmp = symbolList.indexOf('-')) != -1) { // 同時出現 + - 從左至右運算 if (index < tmp) { value = numList.remove(index) + numList.remove(index); } else { index = tmp; value = numList.remove(index) - numList.remove(index); } } else if (index != -1) { value = numList.remove(index) + numList.remove(index); } else if ((index = symbolList.indexOf('-')) != -1) { value = numList.remove(index) - numList.remove(index); } // 刪除運算符 symbolList.remove(index); // 將計算結果放回列表,待下次計算 numList.add(index, value); } }
個人方法是先從括號的算起,根據運算符索引查找運算數索引,從而進行計算,算完後刪除運算符和運算數,並將運算結果放回待運算的列表java