AKing-

151. 表达式计算4

AcWing
来源151. 表达式计算4

栈模拟计算器表达式的计算

首先明确加减号的优先级低于乘除号,乘除号的优先级低于乘方号

stack<ll> nums;存放数
stack<char> ops;存放符号

由于此题符号可能会出现不匹配的状况,所以我们进行字符串的补充,向字符串的前面加上str.size()个\'(\',在字符串最后再加上一个\')\',因为我们是从左往右看的,就可以一定使所有计算都正常进行了

对于一个表达式,如果单看一个 +号 我们无法判断是否需要计算,因为我们不知道下一个符号的优先级,所以我们可以多个符号一起看

对于加减号,每当我们看遇见一个加减号,我就去找符号栈的栈顶,也就是离这个符号最近的符号,只要不是\'(\',都进行计算前面的符号,因为我们知道,加减号级别最低,要放在最后计算,等算完我们再把当前加减号加入栈中

对于乘除号同理,乘除号往前看,看到和自己级别一样或比自己级别高的先算,然后把自己放入栈

对于乘方,往前找乘方,找到就算,然后加入栈

最后遍历到\')\',这使,从右往左,就可以放心算了,也就是一次把栈算完,模拟一下就明白了

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;

stack<int> nums;
stack<char> ops;

void cal(){
    char c = ops.top();
    ops.pop();
    int a = nums.top();
    nums.pop();
    int b = nums.top();
    nums.pop();
    int res = 0;
    if(c == \'+\') res = b + a;
    else if(c == \'-\') res = b - a;
    else if(c == \'*\') res = b * a;
    else if(c == \'/\') res = b / a;
    else{
        res = 1;
        while(a--){
            res *= b;
        }
    }
    nums.push(res);
}

int main(){
    string str;
    string left;
    cin >> str;
    for(int i = 0;i < str.size();i++) left += \'(\';
    str = left + str + \')\';
    // cout << str;
    for(int i = 0;i < str.size();i++){
        if(str[i] <= \'9\' && str[i] >= \'0\'){
            int j = i, t = 0;
            while(str[j] <= \'9\' && str[j] >= \'0\'){//如果后面是数字,就找到这个数字
                t = t * 10 + str[j] - \'0\';
                j++;
            }
            i = j - 1;
            nums.push(t);
        }
        else
        {
            char c = str[i];
            if(c == \'+\' || c == \'-\'){
                if(c == \'-\' && !(str[i - 1] <= \'9\' && str[i - 1] >= \'0\' || str[i - 1] == \')\')){
                    //如果是符号,且前面不是数字和\')\',那么一定是\'(\',直接当成一个负数加入栈
                    int j = i + 1, t = 0;
                    while(str[j] <= \'9\' && str[j] >= \'0\'){//如果后面是数字,就找到这个数字
                        t = t * 10 + str[j] - \'0\';
                        j++;
                    }
                    i = j - 1;
                    nums.push(-t);
                    
                    if(str[i + 1] == \'(\') ops.push(c);
                }
                else{
                    while(ops.top() != \'(\') cal();
                    ops.push(c);
                }
            }else if(c == \'*\' || c == \'/\'){
                while(ops.top() == \'*\' || ops.top() == \'/\' || ops.top() == \'^\') cal();
                ops.push(c);
            }else if(c == \'^\'){
                while(ops.top() == \'^\') cal();
                ops.push(c);
            }else if(c == \')\'){
                while(ops.top() != \'(\') cal();
                ops.pop();
            }else if(c == \'(\'){
                ops.push(c);
            }
        }
    }
    cout << nums.top() << endl;
    return 0;
}

分类:

技术点:

相关文章:

  • 2022-01-26
  • 2021-12-19
  • 2021-11-06
  • 2021-05-26
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-22
猜你喜欢
  • 2021-08-10
  • 2021-11-27
  • 2022-01-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案