AI刷题之简单四则运算解释器 | 豆包MarsCode AI刷题

83 阅读3分钟

“简单四则运算解释器”题目要求

一、问题描述

实现一个基本的计算器来计算一个简单的字符串表达式的值。注意事项如下:

  • 输入是一个字符串表达式(可以假设所给定的表达式都是有效的)
  • 字符串表达式可以包含的运算符号为:左括号 (, 右括号 ), 加号 +, 减号 -
  • 可以包含的数字为:非负整数(< 10)
  • 字符串中不包含空格
  • 处理除法 case 的时候,可以直接省略小数部分结果,只保留整数部分参与后续运算
  • 请不要使用内置的库函数 eval

二、测试样例

输入样例

  • 1+1
  • 3+4*5/(3+2)
  • 4+2*5-2/1
  • (1+(4+5+2)-3)+(6+8)

输出样例

  • 2
  • 7
  • 12
  • 23

三、题目解析

3.1代码思路

  1. 导入及初始化栈:使用栈数据结构来处理表达式的计算,初始化的两个栈:numbers 用于存储数字,operators 用于存储运算符。
  2. 数据处理:遍历输入的字符串表达式,逐个字符进行处理。如果当前字符是数字,将其转换为整数并压入 numbers 栈。如果数字是多位数,继续读取后续字符,直到遇到非数字字符。
  3. 左右括号处理:如果当前字符是左括号 (,将其压入 operators 栈。如果当前字符是右括号 ),从 operators 栈中弹出运算符并进行计算,直到遇到左括号 (
  4. 处理运算符:- 如果当前字符是运算符(+-*/),根据运算符的优先级决定是否立即进行计算。如果栈顶运算符的优先级高于或等于当前运算符,从 operators 栈中弹出运算符并进行计算。然后将当前运算符压入 operators 栈。最后,遍历完表达式后,处理 operators 栈中剩余的运算符,直到栈为空。
  5. 定义 hasPrecedence 方法:定义一个静态方法 hasPrecedence,用于判断运算符的优先级。
  • 如果 op2 是括号,返回 false
  • 如果 op1 是乘法或除法,op2 是加法或减法,返回 false
  • 否则返回 true
  1. 定义 applyOperation 方法:定义一个静态方法 applyOperation,用于执行具体的计算操作。从 numbers 栈中弹出两个数字 a 和 b,从 operators 栈中弹出一个运算符 op。根据运算符执行相应的计算,并将结果压入 numbers 栈。

3.2详细代码


public class Main {
    public static int solution(String expression) {
        Stack<Integer> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();
        
        for (int i = 0; i < expression.length(); i++) {
            char ch = expression.charAt(i);
            
            if (Character.isDigit(ch)) {
                // 处理数字
                int num = ch - '0';
                while (i + 1 < expression.length() && Character.isDigit(expression.charAt(i + 1))) {
                    num = num * 10 + (expression.charAt(++i) - '0');
                }
                numbers.push(num);
            } else if (ch == '(') {
                // 处理左括号
                operators.push(ch);
            } else if (ch == ')') {
                // 处理右括号
                while (!operators.isEmpty() && operators.peek() != '(') {
                    // 计算括号内的表达式
                    applyOperation(numbers, operators);
                }
                operators.pop(); // 弹出左括号
            } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
                // 处理运算符
                while (!operators.isEmpty() && hasPrecedence(ch, operators.peek())) {
                    // 计算优先级高的运算符
                    applyOperation(numbers, operators);
                }
                operators.push(ch);
            }
        }
        
        // 处理剩余的运算符
        while (!operators.isEmpty()) {
            applyOperation(numbers, operators);
        }
        
        return numbers.pop();
    }
    
    // 判断运算符优先级
    private static boolean hasPrecedence(char op1, char op2) {
        if (op2 == '(' || op2 == ')') {
            return false;
        }
        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) {
            return false;
        }
        return true;
    }
    
    // 执行计算操作
    private static void applyOperation(Stack<Integer> numbers, Stack<Character> operators) {
        int b = numbers.pop();
        int a = numbers.pop();
        char op = operators.pop();
        int result = 0;
        
        switch (op) {
            case '+':
                result = a + b;
                break;
            case '-':
                result = a - b;
                break;
            case '*':
                result = a * b;
                break;
            case '/':
                result = a / b; // 整数除法
                break;
        }
        
        numbers.push(result);
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution("1+1") == 2);
        System.out.println(solution("3+4*5/(3+2)") == 7);
        System.out.println(solution("4+2*5-2/1") == 12);
        System.out.println(solution("(1+(4+5+2)-3)+(6+8)") == 23);
    }
}

四、知识总结

  • 栈的使用:使用两个栈 numbers 和 operators 来处理表达式的计算。
  • 优先级处理:通过 hasPrecedence 方法判断运算符的优先级,决定是否立即进行计算。
  • 计算逻辑:通过 applyOperation 方法执行具体的计算操作。
  • 多位数处理:在处理数字时,检查是否是多位数,并将其转换为整数。
  • 除法处理:在 applyOperation 方法中,使用整数除法 a / b 来确保结果为整数。