中缀表达式求值

中缀表达式求值

思路: 用哈希表映射运算符的优先级,两栈(数字栈和运算符栈)来动态维护整个表达式使其达到最简化。

步骤:

  1. 若是数字就将整个数字加进数字栈
  2. 若是(,就将左括号加入运算符栈
  3. 若是),就计算出()中的表达式,这里从栈中取出元素是从右到左取出的,要注意-,/前后的数字不能反
  4. 若是运算符就直接算,直至运算符栈为空

acwing3302. 表达式求值
在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <stack>
#include <unordered_map>
using namespace std;
//哈希映射一下运算符的优先级
unordered_map<char, int> p{{'-', 1}, {'+', 1}, {'*', 2}, {'/', 2}};
//两栈,num存数字,op存运算符和()
stack<int> num;
stack<char> op;

//计算相邻两个数
void eval()
{
    /*这里的a,b插入num栈的运算顺序不能反,对于*和+无所谓,但对于-和/来说,
    顺序就不能反,栈中取出后是从右边往左边算*/
    int b = num.top();      num.pop();
    int a = num.top();      num.pop();
    char c = op.top();      op.pop();
    if(c == '+')    num.push(a + b);
    else if(c == '-')   num.push(a - b);
    else if(c == '*')   num.push(a * b);
    else if(c == '/')   num.push(a / b);
}

int main()
{
    string s;
    cin >> s;
    for(int i = 0; i < s.size(); i ++ )
    {
        if(isdigit(s[i]))   //如果是数字
        {
            int j = i, x = 0;   //这里就相当于双指针,若s[i]是数字,就找到不是数字为止,加到栈中
            while(j < s.size() && isdigit(s[j]))    
                x = x * 10 + s[j ++ ] - '0';

            num.push(x);
            i = j - 1;  //加完后更新i,防止重复加入,j - 1后经过i++,i刚好指向运算符
        }
    
        else if(s[i] == '(')    op.push(s[i]);      //左括号,直接加进去
        else if(s[i] == ')')    //右括号,进行计算括号里的内容,直至消掉括号
        {
            while(op.size() && op.top() != '(') 
                eval();
            op.pop();   //删掉左括号
        }
        else    //正常的运算符
        {
             //若是栈中运算符优先级>=所枚举到的,说明可以进行运算操作
            while(op.size() && p[op.top()] >= p[s[i]])    //如果op.top()是左括号,将返回一个错误值 
                eval();
            //操作完后或是不用操作,都将枚举到的运算发加入到op运算符栈
            op.push(s[i]);
        }
    }
    while(op.size())    eval();     //将没有算完的算完
    cout << num.top() << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值