思路
中缀表达式适合人类阅读和计算,但是对于计算机来说,后缀表达式更合适。先把中缀表达式转换为后缀表达式,然后就可以轻松计算出后缀表达式的结果。
代码
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.Deque;import java.util.LinkedList;import java.util.List;public class Main {public static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String expression = reader.readLine().trim();List<String> infixList = infixToList(expression);System.out.println(infixList);List<String> postfixList = infixToPostfix(infixList);System.out.println(postfixList);int ans = calculate(postfixList);System.out.println(ans);}/*** 将中缀表达式的符号, 数字以List的形式存储** @param expression 中缀表达式* @return List*/private static List<String> infixToList(String expression) {List<String> ans = new LinkedList<String>();char[] chars = expression.toCharArray();for (int begin = 0, i = 0; i < chars.length; ) {// 符号if ((chars[i] < '0') || (chars[i] > '9')) {ans.add(chars[i] + "");++i;begin = i;} else { // 整字while ((i < chars.length) && (chars[i] >= '0') && (chars[i] <= '9')) {++i;}ans.add(expression.substring(begin, i));begin = i;}}return ans;}/*** 中缀表达式数组转后缀表达式数组** @param infixList 中缀表达式数组* @return 后缀表达式数组*/private static List<String> infixToPostfix(List<String> infixList) {List<String> ans = new ArrayList<>(infixList.size());// 符号栈Deque<String> stack = new LinkedList<>();for (String e : infixList) {if (e.equals("(")) { // 左括号直接入栈stack.push(e);} else if (e.equals(")")) { // 右括号入栈时, 一直出栈直到遇到将知道一个左括号while (!stack.peek().equals("(")) {// 栈顶元素出栈入队ans.add(stack.pop());}// 左括号直接出栈stack.pop();} else if (isOperator(e)) { // 遇到操作符// 栈为空或者栈顶元素优先级低则入栈if (stack.isEmpty() || (getPriority(stack.peek()) < getPriority(e))) {stack.push(e);} else {// 栈不为空且栈顶元素不为左括号且栈顶元素优先级大于党员元素, 则持续出栈入队while ((!stack.isEmpty()) && (!stack.peek().equals("("))&& (getPriority(stack.peek()) >= getPriority(e))) {ans.add(stack.pop());}stack.push(e);}} else { // 遇到数字, 直接入队ans.add(e);}}while (!stack.isEmpty()) {ans.add(stack.pop());}return ans;}/*** 判断s是否为操作符** @param s 输入字符串* @return s是操作符返回true, 否则返回false*/private static boolean isOperator(String s) {return s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/");}/*** 栈中元素优先级** @param s 字符串* @return 该符号优先级*/private static int getPriority(String s) {switch (s) {case "+":case "-":return 1;case "*":case "/":return 2;}// 左括号优先级最低return -1;}/*** 后缀表达式求值** @param list 后缀表达式数组* @return 计算结果*/private static int calculate(List<String> list) {// 结果栈Deque<Integer> stack = new LinkedList<>();int num1, num2;for (String e : list) {if (isOperator(e)) {num2 = stack.pop();num1 = stack.pop();switch (e) {case "+":stack.push(num1 + num2);break;case "-":stack.push(num1 - num2);break;case "*":stack.push(num1 * num2);break;case "/":stack.push(num1 / num2);break;}} else {stack.push(Integer.parseInt(e));}}return stack.pop();}}
