题解 | #四则运算#
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
import java.util.Scanner; import java.util.Stack; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s = sc.next(); int length = s.length(); // 存储临时得到的数字 int num = 0; // 数字的符号 int sign = 1; // 存储是否有数字 boolean hasNum = false; // 后缀表达式,用集合存储 List<Object> postfix = new ArrayList<>(); // 存储运算符的栈 Stack<Character> stack1 = new Stack<>(); // 1. 遍历中缀表达式,得到后缀表达式 for (int i = 0; i < length; i++) { char c = s.charAt(i); // 如果是数字,更新数字大小 if (Character.isDigit(c)) { num = num * 10 + c - '0'; hasNum = true; } else { // 不是数字 // 如果有,将之前的num放进去 if (hasNum) { postfix.add(num * sign); // 重置数字相关标记 sign = 1; num = 0; hasNum = false; } // 负号,特点:在第一个位置,或者前面有左括号 if (c == '-' && (i == 0 || isLeftBracket(s.charAt(i - 1)))) { sign = -1; } else if (isRightBracket(c)) { // 右括号 // 直到碰到左括号之前 while (!isLeftBracket(stack1.peek())) { // 弹出运算符号,加入后缀表达式 postfix.add(stack1.pop()); } // 弹出并消除左括号,不能加入后缀表达式 stack1.pop(); } else { // 其它操作符号,包括左括号 // 如果c不优先,将栈顶符号弹出来送后缀表达式 while (!stack1.isEmpty() && !prior(c, stack1.peek())) { postfix.add(stack1.pop()); } // c优先(或空栈),压栈 stack1.push(c); } } } // 如果还有数字,添加进去 if (hasNum) { postfix.add(num * sign); } // 弹出剩下的运算符 while (!stack1.isEmpty()) { postfix.add(stack1.pop()); } // 测试 // System.out.print("后缀表达式:"); // for (Object o : postfix) { // System.out.print(" " + o); // } // System.out.println(); // 2. 计算后缀表达式 // 存储操作数的栈 Stack<Integer> stack2 = new Stack<>(); // 遍历后缀表达式 for (Object o : postfix) { // 是数字 if (o.getClass() == Integer.class) { // 压栈 stack2.push((Integer)o); } else { // 是运算符 // 弹出两个数字 int num1 = stack2.pop(); int num2 = stack2.pop(); // 计算运算结果 int result = calculate(num2, num1, (char)o); // 结果压栈 stack2.push(result); } } // 最后的栈顶元素即为结果 System.out.println(stack2.pop()); } // 是否为运算符 public static boolean isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } // 是否为左括号 public static boolean isLeftBracket(char c) { return c == '(' || c == '[' || c == '{'; } // 是否为右括号 public static boolean isRightBracket(char c) { return c == ')' || c == ']' || c == '}'; } // 是否c1比c2更优先 public static boolean prior(char c1, char c2) { // 左括号进来前优先级最高,进来后优先级最低 if (isLeftBracket(c1) || isLeftBracket(c2)) { return true; } // 乘除比加减优先 if ((c1 == '*' || c1 == '/') && (c2 == '+' || c2 == '-')) { return true; } return false; } // 根据操作符号计算结果并返回 public static int calculate(int a, int b, char c) { if (c == '+') { return a + b; } else if (c == '-') { return a - b; } else if (c == '*') { return a * b; } else { return a / b; } } }