题解 | #四则运算#

四则运算

http://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e

import java.io.*;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        str = str.replace("[","("); // 将括号统一为小括号
        str = str.replace("]",")");
        str = str.replace("{","(");
        str = str.replace("}",")");
        System.out.println(solve(str));
    }
    
  /*
  	递归思想,从内到外处理括号,用栈存放操作数和中间结果。
    +运算符直接入栈,-运算符乘-1入栈,乘除运算符计算完入栈,
    最终栈内所有数相加即是结果
  */
    public static int solve(String s) {
        Stack<Integer> nums = new Stack<>(); // 存放操作数和中间计算结果
        char[] expr = s.toCharArray();
        // 初始数字
        int num = 0;
        // 初始运算符(让第一个数字直接入栈)
        char sign = '+';
        for (int i =0; i < s.length(); i ++) {
            char ch = expr[i]; // 当前字符
            if (ch == ' ') continue; // 是空格,跳过
            if (Character.isDigit(ch)) { // 是数字,进行拼接
                num = num*10 + (ch - '0');
            }
            if (ch == '(') { // 是左括号,应当进入递归
                // 找到当前左括号对应的右括号
                int j = i + 1;
                int count = 1;
                while (count > 0) { // count为0时的j即是对应右括号的索引
                    if (expr[j] == ')') count--;
                    if (expr[j] == '(') count++;
                    j++;
                }
                // 使用左右括号的对应索引进行递归,计算括号内表达式
                num = solve(s.substring(i+1, j-1));
                i = j - 1; // 计算完后更新索引(跳过计算完成的括号)
            }
            // 遇到符号,对操作数进行相应的处理后入栈(处理上一个符号)
            if (!Character.isDigit(ch) || i == s.length() - 1) {
                if (sign == '+') {
                    nums.push(num); // 上一个符号是加号,直接把操作数入栈
                }
                else if (sign == '-') {
                    nums.push(-1*num); // 上一个符号是减号,操作数取反再
                }
                else if (sign == '*') {
                    nums.push(nums.pop()*num); // 上一个符号是乘号,把乘号前面的操作数取出来进行计算再入栈
                }
                else if (sign == '/') {
                    nums.push(nums.pop()/num); // 上一个符号是除号,把乘号前面的操作数取出来进行计算再入栈
                }
                sign = ch; // 把符号更新为当前符号
                num = 0; // 把操作数重置为零
            }
        }
        
        int res = 0;
        while (!nums.isEmpty()) {
            res += nums.pop(); // 栈内数据相加即是结果
        }
        return res;
    }

}
全部评论
妙啊,很简洁易懂;
点赞 回复 分享
发布于 2023-03-04 14:33 广东
初始运算符赋予+,保证后续遍历是遇到运算符进行小结算
点赞 回复 分享
发布于 2023-08-19 10:35 湖北

相关推荐

杨柳哥:这不是普通人,那这个钱的是天才
点赞 评论 收藏
分享
11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
昨天 22:55
已编辑
叮咚买菜
牛客吹哨人:建议细说...哨哥晚点统一更新到黑名单:不要重蹈覆辙!25届毁意向毁约裁员黑名单https://www.nowcoder.com/discuss/1317104
叮咚买菜稳定性 10人发布 投递叮咚买菜等公司10个岗位 >
点赞 评论 收藏
分享
12 5 评论
分享
牛客网
牛客企业服务