题解 | #四则运算#

四则运算

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;
        }
    }
}

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务