解题思路

  1. 这是一个表达式求值问题,需要处理四则运算和括号
  2. 主要解题步骤:
    • 将中缀表达式转换为后缀表达式(逆波兰表达式)
    • 计算后缀表达式的值
  3. 具体实现:
    • 使用两个栈,一个用于存储运算符,一个用于存储操作数
    • 处理运算符优先级:括号 > 乘除 > 加减
    • 遇到数字直接输出到后缀表达式
    • 遇到运算符需要比较优先级,高优先级的运算符可以直接入栈

代码

#include <iostream>
#include <stack>
#include <string>
#include <cctype>
using namespace std;

// 判断运算符优先级
int priority(char op) {
    if (op == '*' || op == '/') return 2;
    if (op == '+' || op == '-') return 1;
    return 0;
}

int calculate(string s) {
    stack<int> nums;
    stack<char> ops;
    
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == ' ') continue;
        
        if (isdigit(s[i])) {
            int num = 0;
            while (i < s.length() && isdigit(s[i])) {
                num = num * 10 + (s[i] - '0');
                i++;
            }
            i--;
            nums.push(num);
        }
        else if (s[i] == '(') {
            ops.push(s[i]);
        }
        else if (s[i] == ')') {
            while (!ops.empty() && ops.top() != '(') {
                char op = ops.top();
                ops.pop();
                int b = nums.top(); nums.pop();
                int a = nums.top(); nums.pop();
                
                if (op == '+') nums.push(a + b);
                else if (op == '-') nums.push(a - b);
                else if (op == '*') nums.push(a * b);
                else if (op == '/') nums.push(a / b);
            }
            ops.pop(); // 弹出 '('
        }
        else { // 运算符
            while (!ops.empty() && ops.top() != '(' && priority(ops.top()) >= priority(s[i])) {
                char op = ops.top();
                ops.pop();
                int b = nums.top(); nums.pop();
                int a = nums.top(); nums.pop();
                
                if (op == '+') nums.push(a + b);
                else if (op == '-') nums.push(a - b);
                else if (op == '*') nums.push(a * b);
                else if (op == '/') nums.push(a / b);
            }
            ops.push(s[i]);
        }
    }
    
    while (!ops.empty()) {
        char op = ops.top();
        ops.pop();
        int b = nums.top(); nums.pop();
        int a = nums.top(); nums.pop();
        
        if (op == '+') nums.push(a + b);
        else if (op == '-') nums.push(a - b);
        else if (op == '*') nums.push(a * b);
        else if (op == '/') nums.push(a / b);
    }
    
    return nums.top();
}

int main() {
    string expr;
    getline(cin, expr);
    cout << calculate(expr) << endl;
    return 0;
}
import java.util.*;

public class Main {
    // 判断运算符优先级
    private static int priority(char op) {
        if (op == '*' || op == '/') return 2;
        if (op == '+' || op == '-') return 1;
        return 0;
    }
    
    public static int calculate(String s) {
        Stack<Integer> nums = new Stack<>();
        Stack<Character> ops = new Stack<>();
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ' ') continue;
            
            if (Character.isDigit(c)) {
                int num = 0;
                while (i < s.length() && Character.isDigit(s.charAt(i))) {
                    num = num * 10 + (s.charAt(i) - '0');
                    i++;
                }
                i--;
                nums.push(num);
            }
            else if (c == '(') {
                ops.push(c);
            }
            else if (c == ')') {
                while (!ops.empty() && ops.peek() != '(') {
                    char op = ops.pop();
                    int b = nums.pop();
                    int a = nums.pop();
                    
                    if (op == '+') nums.push(a + b);
                    else if (op == '-') nums.push(a - b);
                    else if (op == '*') nums.push(a * b);
                    else if (op == '/') nums.push(a / b);
                }
                ops.pop(); // 弹出 '('
            }
            else { // 运算符
                while (!ops.empty() && ops.peek() != '(' && priority(ops.peek()) >= priority(c)) {
                    char op = ops.pop();
                    int b = nums.pop();
                    int a = nums.pop();
                    
                    if (op == '+') nums.push(a + b);
                    else if (op == '-') nums.push(a - b);
                    else if (op == '*') nums.push(a * b);
                    else if (op == '/') nums.push(a / b);
                }
                ops.push(c);
            }
        }
        
        while (!ops.empty()) {
            char op = ops.pop();
            int b = nums.pop();
            int a = nums.pop();
            
            if (op == '+') nums.push(a + b);
            else if (op == '-') nums.push(a - b);
            else if (op == '*') nums.push(a * b);
            else if (op == '/') nums.push(a / b);
        }
        
        return nums.peek();
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String expr = sc.nextLine();
        System.out.println(calculate(expr));
    }
}
def priority(op):
    if op in ['*', '/']: return 2
    if op in ['+', '-']: return 1
    return 0

def calculate(s):
    nums = []  # 数字栈
    ops = []   # 运算符栈
    i = 0
    
    while i < len(s):
        if s[i] == ' ':
            i += 1
            continue
            
        if s[i].isdigit():  # 数字
            num = 0
            while i < len(s) and s[i].isdigit():
                num = num * 10 + int(s[i])
                i += 1
            nums.append(num)
            continue
            
        if s[i] == '(':  # 左括号
            ops.append(s[i])
        elif s[i] == ')':  # 右括号
            while ops and ops[-1] != '(':
                op = ops.pop()
                b = nums.pop()
                a = nums.pop()
                if op == '+': nums.append(a + b)
                elif op == '-': nums.append(a - b)
                elif op == '*': nums.append(a * b)
                elif op == '/': nums.append(a // b)
            ops.pop()  # 弹出 '('
        else:  # 运算符
            while ops and ops[-1] != '(' and priority(ops[-1]) >= priority(s[i]):
                op = ops.pop()
                b = nums.pop()
                a = nums.pop()
                if op == '+': nums.append(a + b)
                elif op == '-': nums.append(a - b)
                elif op == '*': nums.append(a * b)
                elif op == '/': nums.append(a // b)
            ops.append(s[i])
        i += 1
    
    while ops:
        op = ops.pop()
        b = nums.pop()
        a = nums.pop()
        if op == '+': nums.append(a + b)
        elif op == '-': nums.append(a - b)
        elif op == '*': nums.append(a * b)
        elif op == '/': nums.append(a // b)
    
    return nums[0]

expr = input()
print(calculate(expr))

算法及复杂度

  • 算法:栈实现的四则运算表达式求值
  • 时间复杂度: - 其中 为表达式的长度
  • 空间复杂度: - 需要两个栈来存储数字和运算符