题解:AcWing 3302 表达式求值

【题目来源】

AcWing:3302. 表达式求值 - AcWing题库

【题目描述】

给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

【输入】

共一行,为给定表达式。

【输出】

共一行,为表达式的结果。

【输入样例】

(2+2)*(1+1)

【输出样例】

8

【解题思路】

6c018de0a48e5261ccad6ea15ecffd08

【算法标签】

《AcWing 3302 表达式求值》 #栈# #表达式求值#

【代码详解】

#include <bits/stdc++.h>
using namespace std;

// 定义两个栈:操作数栈和运算符栈
stack<int> num;  // 存储操作数的栈(整数类型)
stack<char> op;  // 存储运算符的栈(字符类型)

/**
 * 执行栈顶运算:从栈中弹出两个操作数和一个运算符,计算结果后压回栈中
 * 注意:先弹出的是第二个操作数,后弹出的是第一个操作数
 */
void eval()
{
    // 从操作数栈中弹出第二个操作数(栈顶元素)
    auto b = num.top(); 
    num.pop();
  
    // 从操作数栈中弹出第一个操作数
    auto a = num.top(); 
    num.pop();
  
    // 从运算符栈中弹出运算符
    auto c = op.top(); 
    op.pop();
  
    int x;  // 存储运算结果
  
    // 根据运算符执行相应的算术运算
    if (c == '+') 
    {
        x = a + b;  // 加法运算
    }
    else if (c == '-') 
    {
        x = a - b;  // 减法运算
    }
    else if (c == '*') 
    {
        x = a * b;  // 乘法运算
    }
    else 
    {
        x = a / b;  // 除法运算(整数除法)
    }
  
    // 将计算结果压回操作数栈
    num.push(x);
}

int main()
{
    // 定义运算符优先级映射表
    // 优先级数值越大,优先级越高
    unordered_map<char, int> pr = {
        {'+', 1},  // 加法优先级为1
        {'-', 1},  // 减法优先级为1  
        {'*', 2},  // 乘法优先级为2
        {'/', 2}   // 除法优先级为2
    };
  
    string str;  // 存储输入的中缀表达式字符串
    cin >> str;  // 读取表达式
  
    // 遍历表达式中的每个字符
    for (int i = 0; i < str.size(); i++) 
    {
        auto c = str[i];  // 当前字符
      
        // 处理数字字符
        if (isdigit(c)) 
        {
            int x = 0;    // 当前数字的值
            int j = i;    // 用于扫描连续数字的指针
          
            // 提取连续的数字字符,处理多位数
            while (j < str.size() && isdigit(str[j]))
            {
                // 将字符转换为数字并累加
                x = x * 10 + (str[j] - '0');
                j++;
            }
          
            i = j - 1;    // 更新主循环索引,跳过已处理的数字
            num.push(x);  // 将数字压入操作数栈
        } 
        // 处理左括号:直接压入运算符栈
        else if (c == '(') 
        {
            op.push(c);
        }
        // 处理右括号:计算括号内的所有表达式
        else if (c == ')') 
        {
            // 不断计算直到遇到左括号
            while (op.top() != '(') 
            {
                eval();  // 执行计算
            }
            op.pop();  // 弹出左括号
        }
        // 处理运算符:+ - * /
        else 
        {
            // 当栈不为空,且栈顶不是左括号,且栈顶运算符优先级不低于当前运算符时
            while (op.size() > 0 && op.top() != '(' && pr[op.top()] >= pr[c]) 
            {
                eval();  // 先计算优先级高的运算
            }
            op.push(c);  // 当前运算符压栈
        }
    }
  
    // 处理运算符栈中剩余的所有运算
    while (op.size() > 0) 
    {
        eval();
    }
  
    // 输出最终结果(操作数栈中唯一的元素)
    cout << num.top() << endl;
  
    return 0;
}

【运行结果】

(2+2)*(1+1)
8
posted @ 2026-02-21 19:29  团爸讲算法  阅读(10)  评论(0)    收藏  举报