简单四则运算|豆包MarsCode AI刷题

46 阅读3分钟

问题描述

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

测试样例

样例1:

输入:expression = "1+1"
输出:2

样例2:

输入:expression = "3+4*5/(3+2)"
输出:7

样例3:

输入:expression = "4+2*5-2/1"
输出:12

样例4:

输入:expression = "(1+(4+5+2)-3)+(6+8)"
输出:23

样例5:

输入:expression = "2*(5+5*2)/3+(6+8*3)"
输出:40

问题理解

你需要实现一个基本的计算器来计算简单的字符串表达式的值。该字符串表达式有效,并可能包含数字(0-9)、运算符+-*/及括号()。注意,字符串中不包含空格。除法运算应只保留整数结果。

数据结构选择

  1. :我们可以使用两个栈,一个用于存储操作数(数字),另一个用于存储运算符。栈非常适合处理括号和运算符优先级的问题。

算法步骤

  1. 遍历表达式:从左到右遍历表达式中的每个字符。

  2. 解析数字:如果当前字符是数字,解析完整的数字并压入操作数栈。

  3. 处理括号

    • 遇到左括号(时,直接压入运算符栈。
    • 遇到右括号)时,计算直到遇到左括号。
  4. 处理运算符

    • 遇到运算符时,检查运算符栈顶的运算符,如果栈顶运算符优先级较高,则先进行栈顶运算符的计算。
    • 将当前运算符压入运算符栈。
  5. 计算结果:遍历结束后,处理运算符栈中剩余的运算符,直到运算符栈为空。

具体步骤

  1. 初始化两个栈:一个用于操作数,一个用于运算符。

  2. 遍历表达式

    • 如果是数字,解析完整的数字并压入操作数栈。
    • 如果是左括号(,压入运算符栈。
    • 如果是右括号),计算直到遇到左括号。
    • 如果是运算符,处理运算符优先级。
  3. 处理剩余运算符:遍历结束后,处理运算符栈中剩余的运算符。

  4. 返回结果:最终结果在操作数栈的栈顶。

代码如下 import java.util.Stack;

public class Main { public static int solution(String expression) { // 使用两个栈,一个用于操作数,一个用于运算符 Stack numStack = new Stack<>(); Stack opStack = new Stack<>();

    // 遍历表达式中的每个字符
    for (int i = 0; i < expression.length(); i++) {
        char ch = expression.charAt(i);
        
        // 如果是数字,解析完整的数字并压入numStack
        if (Character.isDigit(ch)) {
            int num = 0;
            while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
                num = num * 10 + (expression.charAt(i) - '0');
                i++;
            }
            i--; // 回退一步,因为for循环会再前进一步
            numStack.push(num);
        }
        // 如果是左括号,压入opStack
        else if (ch == '(') {
            opStack.push(ch);
        }
        // 如果是右括号,计算直到遇到左括号
        else if (ch == ')') {
            while (!opStack.isEmpty() && opStack.peek() != '(') {
                // 计算并压入结果
                numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop()));
            }
            opStack.pop(); // 弹出左括号
        }
        // 如果是运算符,处理运算符优先级
        else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
            while (!opStack.isEmpty() && precedence(opStack.peek()) >= precedence(ch)) {
                // 计算并压入结果
                numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop()));
            }
            opStack.push(ch);
        }
    }
    
    // 处理剩余的运算符
    while (!opStack.isEmpty()) {
        numStack.push(applyOp(opStack.pop(), numStack.pop(), numStack.pop()));
    }
    
    // 最终结果在numStack的栈顶
    return numStack.pop();
}

// 计算两个数的运算结果
private static int applyOp(char op, int b, int a) {
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b; // 注意:这里假设b不为0
    }
    return 0;
}

// 返回运算符的优先级
private static int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    return 0;
}

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

}