import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        Stack<Character> opt = new Stack<Character>();
        Stack<Integer> data = new Stack<Integer>();
        int i = 0;
        int addOrSub = 1;
        // 替换一下,简化后续的处理逻辑
        str = str.replaceAll("\\{", "(");
        str = str.replaceAll("\\[", "(");
        str = str.replaceAll("}", ")");
        str = str.replaceAll("]", ")");
        while (i < str.length()) {
            char c = str.charAt(i);
            if (c == '-' && (i == 0 || str.charAt(i - 1) == '(')) {
                // 单纯的负号
                addOrSub = -1;
                i++;
                continue;
            }
            if (isOp(c)) {
                switch (c) {
                    case '(':
                        opt.push(c);
                        i++;
                        break;
                    case ')':
                        // 特殊处理,因为要进行括号的湮灭操作,不是标准的cal操作。
                        char lastO = opt.peek();
                        if (lastO == '(') {
                            // 括号匹配并闭合
                            opt.pop();
                            i++;
                        } else {
                            cal(data, opt);
                        }
                        break;
                    case '+':
                    case '-':
                    case '*':
                    case '/':
                        // 【重要】:优先级绝对高,就进栈,否则就计算;
                        if (!opt.isEmpty() && (priority(c) <= priority(opt.peek()))) {
                            cal(data, opt);
                        } else {
                            opt.push(c);
                            i++;
                        }
                        break;
                    default:
                        // nothing or throw exception;

                }
            } else {
                // 数字字母,
                int j = i;
                int num = 0;
                // 处理连续的数字字符
                while (j < str.length() && !isOp(str.charAt(j))) {
                    num *= 10;
                    num += str.charAt(j) - '0';
                    j++;
                }
                data.push(addOrSub * num);
                i = j; // 保持i跟进
                addOrSub = 1;
            }
        }
        while (!opt.isEmpty()) {
            cal(data, opt);
        }
        System.out.println(data.peek());
    }

    public static int priority(char c) {
        switch (c) {
            case '(':
                return 0;
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
            default:
                // '(' 的优先级更低;优先级越低越要进栈,优先级越高越要计算
                return 0;
        }
    }

    public static void cal(Stack<Integer> data, Stack<Character> opt) {
        char o = opt.pop();
        int b = data.pop();
        int a = data.pop();
        switch (o) {
            case '+':
                data.push(a + b);
                break;
            case '-':
                data.push(a - b);
                break;
            case '*':
                data.push(a * b);
                break;
            case '/':
                data.push(a / b);
                break;
            default:
                // nothing
        }
    }

    public static boolean isOp(char c) {
        return c == '{' || c == '}' || c == '[' || c == ']' || c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/';
    }
}

特点:

  1. 不用记忆复杂的‘逆波兰式’的转换逻辑;
  2. 采用直观计算逻辑写四则计算逻辑;
  3. 注释友好;