青训营X豆包MarsCode技术训练营 | 豆包MarsCode AI刷题02

81 阅读3分钟

简单四则运算

问题描述

小F面临一个编程挑战:实现一个基本的计算器来计算简单的字符串表达式的值。该字符串表达式有效,并可能包含数字(0-9)、运算符+-及括号()。注意,字符串中不包含空格。除法运算应只保留整数结果。请实现一个解析器计算这些表达式的值,且不使用任何内置的eval函数。

屏幕截图 2024-11-23 121051.png

该题目涉及的知识点:堆栈问题,进出

对于这道题,我们的目标是计算一个给定的不含空格且只包含特定运算符和数字的字符串表达式的值。

首先选择使用两个栈,一个栈numStack用于存储数字,另一个栈opStack用于存储运算符,这样可以方便地处理运算符的优先级和括号。

算法步骤如下:

  1. 遍历表达式的每个字符。
  • 如果是数字,将其转换为整数并压入数字栈。
  • 如果是左括号(,直接压入运算符栈。
  • 如果是右括号),则不断从运算符栈取出运算符,并从数字栈取出两个数字进行计算,直到遇到左括号(,然后将结果压入数字栈。
  • 如果是运算符+-*/,则在将其压入运算符栈之前,先检查运算符栈顶的运算符优先级,如果栈顶运算符优先级高于或等于当前运算符,则取出栈顶运算符和数字栈的两个数字进行计算,将结果压入数字栈,然后再将当前运算符压入运算符栈。
  1. 遍历完表达式后,处理剩余的运算符,按照上述规则进行计算,直到运算符栈为空。
import java.util.Stack;
public class Main {
    public static int solution(String expression) {
        // Please write your code here
         // 首先,我们需要创建一个栈来处理括号和运算符的优先级
         Stack<Integer> numStack = new Stack<>();
         Stack<Character> opStack = new Stack<>();
         // 遍历表达式
         for (int i = 0; i < expression.length(); i++) {
             char c = expression.charAt(i);
 
             // 如果是数字,将其转换为整数并压入数字栈
             if (Character.isDigit(c)) {
                 int num = c - '0';
                 numStack.push(num);
             } else if (c == '(') {//将运算符号放进运算符的栈里面
                 opStack.push(c);
                } else if (c == ')') {
                    // 处理括号内的计算
                    while (opStack.peek()!= '(') {
                        // 执行计算操作
                        numStack.push(applyOperation(opStack.pop(), numStack.pop(), numStack.pop()));
                    }
                    opStack.pop(); // 弹出 '('
                } else if (c == '+' || c == '-' || c == '*' || c == '/') {
                    // 处理运算符的优先级
                    while (!opStack.isEmpty() && precedence(opStack.peek()) >= precedence(c)) {
                        // 执行计算操作
                        numStack.push(applyOperation(opStack.pop(), numStack.pop(), numStack.pop()));
                    }
                    opStack.push(c);
                }
            }
            // 处理剩余的运算符
            while (!opStack.isEmpty()) {
                // 执行计算操作
                numStack.push(applyOperation(opStack.pop(), numStack.pop(), numStack.pop()));
            }
            return numStack.peek();
    }

    // 定义运算符优先级的方法
    public static int precedence(char op) {
        if (op == '+' || op == '-') {
            return 1;
        } else if (op == '*' || op == '/') {
            return 2;
        }
        return 0;
    }
    public static int applyOperation(char operator, int b, int a) {
        switch (operator) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                if (b == 0) {
                    throw new RuntimeException("Division by zero");
                }
                return a / b;
        }
        return 0;
    }

    public static void main(String[] args) {
        // You can add more test cases here
        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);
    }
}

豆包AI给出的关键点:

  • 运算符优先级:需要定义一个方法来判断运算符的优先级。
  • 括号的处理:遇到括号时,需要特别处理,确保括号内的表达式优先计算。 在解题过程中遇到卡壳的情况可以询问豆包ai助手,大大提高了解题思路

屏幕截图 2024-11-23 121430.png