[数学杂谈] 如何将中缀表达式转换成后缀表达式


前言

数学杂谈这个东西。。。我好像已经很久没有更新了吧。。。QwQ

当然,今天作为某道题的基础,这当然是必不可少的了。

各种表达式

一个式子能分成三种:前缀表达式,中缀表达式,后缀表达式。

正如其名,前缀表达式就是所有的符号都在前面;中缀表达式呢,就是我们平时用到的式子了;后缀表达式就是所有的运算符都在后面。

一般来说,计算机用到的都是前缀表达式和后缀表达式(反正不会是中缀就行了)
话说好奇怪啊,人类发明的东西,竟然不是按照人类的思维来做??

当然前缀和后缀有个好处,他们的式子中不可能会有括号存在。因为在这两个表达式中,在中缀优先的,这里也能优先,并且不需要括号来限制。

当然,这样说着很抽象,看个式子: 4 ∗ 5 + 4 ∗ ( 6 + 7 ∗ ( 2 + 3 − 5 ) ) ∗ 5 4 * 5 + 4 * (6 + 7 * (2 + 3 - 5)) * 5 45+4(6+7(2+35))5,转换成后缀是这样的: 4   5 ∗ 4   6   7   2   3 + 5 − ∗ + ∗   5 ∗ + 4 \ 5 * 4\ 6\ 7\ 2\ 3 + 5 - * + *\ 5 * + 4 54 6 7 2 3+5+ 5+,前缀就先放一边吧,今天主要是研究中缀转后缀。。。其实是我太蒟了 (逃

后缀表达式的机制呢就是碰到一个运算符后,在找他前面遇到的第 1 、 2 1、 2 12个数字,将其进行运算,然后再找下一个,直到表达式算完。

先贴一下后缀表达式计算的参考代码吧:

Code

#include<cstdio>
#include<stack>
#include<cstdlib>
using namespace std;
stack<int> a;
char s[10];
int x,y,z;
int main()
{
    while(scanf("%s",s)==1)
        if(s[0]>='0'&&s[0]<='9')
        {
            z=atoi(s);//将字符串转化为整形,atof是转化为浮点数
            a.push(z);
        }
        else
        {
            x=a.top();
            a.pop();
            y=a.top();
            a.pop();
            switch(s[0])
            {
                case'+': a.push(x+y);break;
                case'-': a.push(y-x);break;//因为先放进的是被减/除数,后放进的是减/除数,所以要倒过来
                case'*': a.push(x*y);break;
                case'/': a.push(y/x);break;
            }
        }
    x=a.top();
    printf("%d",x);
}

差不多就是这样,看得懂思路就行(我都觉得写得很稚嫩),毕竟是一年前写得嘛

怎么转换

这才是最重要的说

前面已经说了后缀表达式计算的机制了,那么接下来就来讲讲具体转换的步骤:

1. 如果说遇到的是数字的话,那么就可以直接输出,判断下一个
2. 如果说遇到的是左括号的话,先存进去等遇到右括号后再处理
3. 如果说遇到的是运算符的话,那么先存进栈,等碰到下一个运算符时在判断优先级的大小左括号的优先级最低,加减次之,乘除最高(此处不考虑幂)。如果说栈里的那个运算符比当前这个运算符大的话,就说明可以优先输出栈里的了,用while循环判断,如果说栈里的优先级大于等于该运算符的话,就一直输出,否则将该运算符入栈
4. 如果说遇到的右括号的话,就说明这个括号里的运算操作都已经做完了,可以直接一股脑的将栈里左括号之后的输出就 O K OK OK了。
5. 如果说这个串读完了,而栈里还有的话,也就直接输出就可以了。还有一个注意是所有的括号均不输出。

当然,如果还没太懂得可以看看(康康这篇博客这篇也行

Code

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <cstring>
#include <iostream>
using namespace std;
#define reg register
#define LL long long
#define INF 0x3f3f3f3f

template<typename T>
void re (T &x){
    x = 0;
    int f = 1;
    char c = getchar ();
    while (c < '0' || c > '9'){
        if (c == '-') f = -1;
        c = getchar ();
    }
    while (c >= '0' && c <= '9'){
        x = (x << 1) + (x << 3) + c - 48;
        c = getchar ();
    }
    x *= f;
}

template<typename T>
void pr (T x){
    if (x < 0){
        putchar ('-');
        x = ~x + 1;
    }
    if (x / 10) pr (x / 10);
    putchar (x % 10 + 48);
}

string A, B;
int lena;
stack<char> S;

int cmp (char s){
    if (s == '(')
        return 0;
    else if (s == '+' || s == '-')
        return 1;
    else return 2;
}

void transfer (string A){
    lena = A.length ();
    for (int i = 0; i < lena; i++){
        if (A[i] >= '0' && A[i] <= '9'){
            int j;
            for (j = i; j < lena && A[j] >= '0' && A[j] <= '9'; j++)
                B += A[j];
            B += ' ';
            i = j - 1;
        }
        else if (A[i] == 'x'){
            B += A[i];
            B += ' ';
        }
        else if (A[i] == '(')
            S.push (A[i]);
        else if (A[i] == '+' || A[i] == '-' || A[i] == '*'){
            if (S.empty ()){
                S.push (A[i]);
                continue;
            }
            int lev1 = cmp (A[i]), lev2 = cmp (S.top ());
            if (lev1 > lev2) S.push (A[i]);
            else{
                while (!S.empty () && lev1 <= cmp (S.top ())){
                    B += S.top ();
                    B += ' ';
                    S.pop ();
                    if (!S.empty ())
                        lev2 = cmp (S.top ());
                }
                S.push (A[i]);
            }
        }
        else{
            while (S.top () != '('){
                B += S.top ();
                B += ' ';
                S.pop ();
            }
            S.pop ();
        }
    }
    while (!S.empty ()){
        B += S.top ();
        B += ' ';
        S.pop ();
    }
}

int main (){
    cin >> A;
    transfer (A);
    cout << B << endl;
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值