AcWing 3302. 表达式求值

该文章介绍了一种使用两个栈(数字栈和运算符栈)来处理和计算中缀表达式的方法。当遇到数字时,将其压入数字栈;遇到运算符,比较其优先级并进行相应的计算;遇到括号,管理运算符栈。文章提供了C++代码示例,演示了如何解析和求值表达式,特别强调了处理括号和运算符优先级的细节。
摘要由CSDN通过智能技术生成

思路

很简单,就是维护数字和字符两个栈

  1. 读到数字,放入

  2. 读到字符,

    • 字符等级高,直接放入
    • 字符等级低,则把前面高的全都eval一遍(此时注意while循环需要加上op.size()判断),然后放入
  3. 读到左括号,放入,等待右括号

  4. 读到右括号,循环计算,直到读到左括号

    • 计算之后需要手动弹出左括号
  5. eval函数比较好理解,就是挑左右两个数和一个运算符

    • 由于栈是动态维护的且遵循读入的顺序,所以只要存入弹出没有问题,那么配对计算是没有问题的

注意点

  1. 所有的弹出操作都在eval中进行,所以主干不需要维护出栈
    • 除了,需要在主程序中弹出,因为不会进入到eval
  2. while的时候要加上op.size()的判断,不然会SE

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <unordered_map>

using namespace std;

unordered_map<char, int> h {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
stack<int> num;
stack<char> op;

void eval()
{
    int b = num.top();
    num.pop();
    
    int a = num.top();
    num.pop();
    
    char c = op.top();
    op.pop();
    
    int x = 0;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a*b;
    else if (c == '/') x = a/b;
    
    num.push(x);
    
    return ;
}

int main ()
{
    string s;
    cin >> s;
    
    for (int i = 0; i < s.size(); i ++)
    {
        if (isdigit(s[i]))
        {
            int x = 0;
            int j = i;
            while (isdigit(s[j]))
            {
                x = x*10 + s[j] - '0';
                j ++;
            }
            num.push(x);
            i = j-1;
        }
        else if (s[i] == '(')
        {
            op.push(s[i]);
        }
        else if (s[i] == ')')
        {
            while (op.top() != '(')
            {
                eval();
            }
            op.pop();
        }
        else 
        {
            while (op.size() && h[op.top()] >= h[s[i]])
            {
                eval();
            }
            op.push(s[i]);
        }
    }
    
    while (op.size()) eval();
    
    cout << num.top() << endl;
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值