模拟栈

栈的特点:先进后出

数组模拟栈的方法:

tt 指针指向栈顶

插入:tt 指针++

弹出:tt 指针--

判断栈空:tt == 0 ?

询问栈顶元素:stk[tt]

例题

828. 模拟栈 - AcWing题库

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

const int N = 1e5 + 5;
int stk[N], tt;

int main()
{
    int T, x;
    string op;
    cin >> T;
    while(T--)
    {
       cin >> op;
       if(op == "push")
       {
           cin >> x;
           stk[++tt] = x;
       }
       else if(op == "pop")
       {
           --tt;
       }
       else if(op == "empty")
       {
           if(tt == 0) cout << "YES\n";
           else cout << "NO\n";
       }
       else 
       {
           cout << stk[tt] << endl;
       }
    }
    return 0;
}

表达式求值

算法:转换为逆波兰表达式(后缀表达式),工程上往往转换完成后进行计算,其实可以边转换边计算。

首先需要有两个栈:

  • stack<int> num :数字栈
  • stack<char> op :操作栈
  1. 从左到右遍历表达式字符串,如果是数字则压入数字栈
  2. 如果是左括号 ( 压入操作栈
  3. 如果是右括号 ) 不压入栈
    • 遍历操作栈,从中弹出操作符,直到遇到左括号 ( 停止
    • 从数字栈中弹出两个操作数,注意操作数的顺序相反
    • 将计算结果压入数字栈
    • 将左括号 ( 弹出操作栈
  4. 如果是操作符
    • 遍历操作栈,当栈非空,栈顶不为左括号,栈顶操作符的优先级大于当前操作符时:从操作栈中弹出操作符,从数字栈中弹出两个操作数进行计算,并将结果压入数字栈中。
    • 将当前操作符压入栈中
  5. 当表达式遍历完成后,将剩余的操作符计算完成,结果存放在数字栈中,num.top() 即为计算结果

例题

3302. 表达式求值 - AcWing题库

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

stack<int> num;
stack<char> op;

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

int main()
{
    unordered_map<char, int> pr = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
    string str;
    cin >> str;
    int n = str.length();
    for(int i = 0; i < n; ++ i)
    {
        char c = str[i];
        if(isdigit(c))
        {
            int x = 0, j = i;
            while(j < n && isdigit(str[j]))
                x = x * 10 + str[j ++ ] - '0';
            i = j - 1;
            num.push(x);
        }
        else if(c == '(') op.push('(');
        else if(c == ')')
        {
            while(op.top() != '(') cal();
            op.pop();
        }
        else{
            while(!op.empty() && op.top() != '(' && pr[op.top()] >= pr[c])
                cal();
            op.push(c);
        }
    }
    while(!op.empty()) cal();
    cout << num.top() << endl;
    return 0;
}
posted @ 2021-08-03 19:31  xiongyuqing  阅读(91)  评论(0编辑  收藏  举报