STL模板类大法!!

· · 题解

STL模板类太好用了,大佬们看过来嘞!

逆波兰算法是什么我就不多说了,大佬们应该知道的, 不知道的看这里:[逆波兰算法](https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/solution/ji-bai-bai-fen-bai-suan-fa- -by-19ty72/)

我们先构建这一题的基本大框架算法

  1. 读入中缀表达式,将它转成后缀表达式。
  2. 根据后缀表达式算出结果。

第一条有点难。

然后我们需要什么变量,在这里先跟大家说一下:

字符串有可能不完全是操作数,也有可能是运算符(这里没有分界符)

for (i = 0; i < s.length(); i++)

1.如果是操作数,则直接压如栈l。

2 如果是分界符,

I:左括号,压入栈l,等待有括号出现。

II:右括号,while sop顶不是左括号 sop出栈并入到l里面实现运算符反转(为什么后来讲)

找到了之后丢弃左右括号。

3.如果是运算符,将新来的元素(s[i])用op1来表示,sop栈顶用op2来表示,则

I:如果op2不是运算符,则op1与op2没有可比性,op2入栈sop,continue;

II:如果是运算符,则比较优先级(加减乘在一起我要先算乘那种)

一:如果优先级大于op2,则压入栈sop(这就是为什么我在第二点说要实现运算符反转,因为栈是反的)

二:如果优先级小于等于op1,则sop出栈并push_back进l,重复第三条(因为op1没处理完)。

※最终,如果sop还有元素,则依次弹出加入l(有可能是某些优先级最大的运算符)

但没有可能是括号,因为括号已经在第二条中匹配完了并且丢弃了。

接下来,我们就要开始给deque赋值了,关于这个加减乘除乘方的问题,我是说这么解决的:

如果是+,那就是LONG_LONG_MAX-4;//LONG_LONG_MAX是long long 的最大值

如果是-,那就是LONG_LONG_MAX-3;

如果是*,那就是LONG_LONG_MAX-2;

如果是/,那就是LONG_LONG_MAX-1;留点白是好事。

3.在那个双头队列l中,如果l.front()是数字,则直接push到scalc中,如果是大于INT_MAX(int最大值)的,那说明是运算符,那我就把scalc中的上面两个元素出栈,并赋值给num1, num2,再把他们抛给计算函数(自定义),

注意,如果是减法和除法那得反过来,scalc栈出栈顺序是相反的!我们要把算出来的结果再压回给scalc栈,方便下一次遇到运算符运算。

以此类推,最终scalc.top()就是最终结果!

好,BB了这么多,终于上代码了!

#include <bits/stdc++.h>
using namespace std;
string s;
stack<char> sop;
stack<int> scalc;
deque<char> l;
deque<long long> recycle;

void print(deque<char>, deque<long long>);
void Cal();
int com(char);
void op(int, int, char);
void Turn_houzhui();

int com(char c)
{
    if (c == '+' or c == '-') return 1;
    if (c == '*' or c == '/') return 2;
    if (c == '^') return 3;
    return 0;
}
void Turn_houzhui()
{
    for (int i = 0; i < s.length(); i++)
    {
        if (s[i] >= '0' and s[i] <= '9') l.push_back(s[i]);
        else
        {
            if (s[i] == '(' or s[i] == ')')
            {
                if (s[i] == '(') sop.push(s[i]);
                else
                {
                    while (sop.top() != '(')
                    {
                        l.push_back(sop.top());
                        sop.pop();
                    }
                    sop.pop();
                }
            }
            else
            {
                if (sop.empty() or sop.top() == '(')
                {
                    sop.push(s[i]);
                    continue;
                }
                while (com(s[i]) <= com(sop.top()))
                {
                    l.push_back(sop.top());
                    sop.pop();
                    if (sop.empty() or sop.top() == '(')
                    {
                        sop.push(s[i]);
                        break;
                    }
                    else {
                        if (com(s[i]) > com(sop.top()))
                        {
                            sop.push(s[i]);
                            goto WAI;
                        }
                    }
                }
                if (com(s[i]) > com(sop.top())) sop.push(s[i]);
                WAI : continue;
            }
        }
    }
    while (not sop.empty())
    {
        l.push_back(sop.top());
        sop.pop();
    }
    return;
}
void op(int a, int b, char c)
{
    if (c == '+')
    {
        scalc.push(a + b);
        recycle.push_back(a + b);
    }
    if (c == '-')
    {
        scalc.push(a - b);  
        recycle.push_back(a - b);
    }
    if (c == '*')
    {
        scalc.push(a * b);  
        recycle.push_back(a * b);
    }
    if (c == '/')
    {
        scalc.push(a / b);
        recycle.push_back(a / b);
    } 
    if (c == '^')
    {
//      cout << a << " " << b << endl;
        long long temp = a;
        for (int i = 1; i < b; i++) a *= temp;
        scalc.push(a);
//      cout << "a:" << a << endl;2
        recycle.push_back(a);
    }
    return;
}
void print(deque<char> l, deque<long long> recycle)
{
    while (not recycle.empty())
    {
        if (recycle.front() > INT_MAX)
        {
            if (recycle.front() == LONG_LONG_MAX - 4) cout << '+' << ' ';
            else if (recycle.front() == LONG_LONG_MAX - 3) cout << '-' << ' ';
                 else if (recycle.front() == LONG_LONG_MAX - 2) cout << '*' << ' ';
                      else if (recycle.front() == LONG_LONG_MAX - 1) cout << '/' << ' ';
                           else cout << '^';
        }
        else cout << recycle.front() << ' ';
        recycle.pop_front();
    }
    while (not l.empty())
    {
        cout << l.front() << ' ';
        l.pop_front();
    }
    cout << endl;
    return;
}
void test (deque<char> x)
{
    while (not x.empty())
    {
        cout << x.front() << ' ';
        x.pop_front();
    }
    cout << endl;
    return;
}
void Cal()
{
    int num1 = 0, num2 = 0;
    test(l);
    while (not l.empty())
    {
        bool calcu = false;
        if (l.front() >= '0' and l.front() <= '9') scalc.push(l.front() - '0');
        else if (l.front() == '+' or l.front() == '-' or l.front() == '*' or l.front() == '/' or l.front() == '^')
        {
            num1 = scalc.top(); scalc.pop();
            num2 = scalc.top(); scalc.pop();
            recycle.pop_back(); recycle.pop_back();
            calcu = true;
            if (l.front() == '+' or l.front() == '*') op(num1, num2, l.front());
            else op(num2, num1, l.front());
        }
        if ((l.front() < '0' or l.front() > '9') and calcu == false) {
            if (l.front () == '+') recycle.push_back(LONG_LONG_MAX - 4);
            else if (l.front() == '-') recycle.push_back(LONG_LONG_MAX - 3);
                 else if (l.front () == '*') recycle.push_back(LONG_LONG_MAX - 2);
                      else if (l.front() == '/') recycle.push_back(LONG_LONG_MAX - 1);
                           else recycle.push_back(LONG_LONG_MAX);
        }
        else if (calcu == false) recycle.push_back(l.front() - '0');
        l.pop_front();
        if (calcu) print(l, recycle);
    }
    scalc.pop();
    return;
}
int main ()
{
    getline(cin, s);
    Turn_houzhui();
    Cal();
    return 0;
}