波兰表达式、逆波兰表达式

中缀表达式

中缀表达式是最常见的运算表达式,如:3 + 5 * (2 + 6) - 1

波兰表达式

波兰表达式又称为前缀表达式,它是由中缀表达式经过一定的方式转换来的
比如中缀表达式为:3+5x(2+6)-1 对应的前缀表达式为:- + 3 x 5 + 2 6 1

对于中缀表达式从右向左遍历转换为前缀表达式,中途要是用进行存储
转换规则如下:

  • 当遇到右括号时,直接将其压入栈中
  • 当遇到左括号时,将栈中的内容陆续出栈,并将其归入到前缀表达式中,直到遇到右括号,最后将右括号出栈,此时右括号并不归入前缀表达式
  • 当遇到操作数时,直接将其归入到前缀表达式中
  • 如果是其他的操作符,比较当前操作符与栈中栈顶操作符的优先级,如果当前操作符的优先级大于或等于栈顶操作符的优先级,直接当前操作符压入栈中,如果当前操作符的优先级小于栈顶操作符的优先级,将栈顶的操作符出栈,并归入到前缀表达式中,直到当前操作符的优先级大于或等于栈顶操作符的优先级,将当前操作符压入栈中
  • 当上述步骤完成后,如果当前栈不为空,将当前栈中的元素依次出栈,并归入到前缀表达式中。
  • 最后逆序输出前缀表达式即可得到最终的结果。

波兰表达式代码:

前提规定:假设表达式中只存在如下符号:左括号、右括号、加、减、乘、除

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

stack<char> sta;
char ch[50],res[50];
int ind;

int main()
{
    scanf("%s",ch);
    int len = strlen(ch);
    for(int i=len-1;i>=0;--i)
    {
        if(ch[i]>='0' && ch[i]<='9')
        {
            res[ind++] = ch[i];
            continue;
        }
        if(ch[i]=='+' || ch[i]=='-')
        {
            while(!sta.empty()&&(sta.top()=='*' || sta.top()=='/'))
            {
                res[ind++] = sta.top();
                sta.pop();
            }
            sta.push(ch[i]);
            continue;
        }
        if(ch[i]=='*' || ch[i]=='/')
        {
            sta.push(ch[i]);
            continue;
        }
        if(ch[i] == ')')
        {
            sta.push(ch[i]);
            continue;
        }
        if(ch[i] == '(')
        {
            while(!sta.empty()&&sta.top()!=')')
            {
                res[ind++] = sta.top();
                sta.pop();
            }
            if(!sta.empty())
                sta.pop();
        }
    }
    while(!sta.empty())
    {
        res[ind++] = sta.top();
        sta.pop();
    }
    for(int i=ind-1;i>=0;--i)
        printf("%c",res[i]);

    return 0;
}

逆波兰表达式

逆波兰表达式又称为后缀表达式,由中缀表达式按照一定的方式转换而来的
比如中缀表达式为:3+5x(2+6)-1 对应的后缀表达式为:3526+x1-+
此转换同样需要来存储操作符,转换规则如下:

  • 转换是从左向右进行遍历进行转换
  • 当遇到左括号时,直接将其压入栈中
  • 当遇到右括号时,将栈中的内容陆续出栈,并将其归入到后缀表达式中,直到遇到左括号,最后将左括号出栈,此时左括号并不归入后缀表达式
  • 当遇到操作数时,直接将其归入到后缀表达式中
  • 如果是其他的操作符,比较当前操作符与栈中栈顶操作符的优先级,如果当前操作符的优先级大于或等于栈顶操作符的优先级,直接当前操作符压入栈中,如果当前操作符的优先级小于栈顶操作符的优先级,将栈顶的操作符出栈,并归入到后缀表达式中,直到当前操作符的优先级大于或等于栈顶操作符的优先级,将当前操作符压入栈中
  • 当上述步骤完成后,如果当前栈不为空,将当前栈中的元素依次出栈,并归入到后缀表达式中。
  • 最后正序输出即可。

逆波兰表达式代码:

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

stack<char> sta;
char sour[100],res[100];
int ind;

int main()
{
    scanf("%s",sour);
    int len = strlen(sour);
    for(int i=0;i<len;++i)
    {
        if(sour[i]=='(')
        {
            sta.push(sour[i]);
            continue;
        }
        if(sour[i]>='0'&&sour[i]<='9')
        {
            res[ind++] = sour[i];
            continue;
        }
        if(sour[i]=='+'||sour[i]=='-')
        {
            while(!sta.empty()&&(sta.top()=='*'||sta.top()=='/'))
            {
                res[ind++] = sta.top();
                sta.pop();
            }
            sta.push(sour[i]);
            continue;
        }
        if(sour[i]==')')
        {
            while(!sta.empty()&&sta.top()!='(')
            {
                res[ind++] = sta.top();
                sta.pop();
            }
            sta.pop();
            continue;
        }
        if(sour[i]=='*'||sour[i]=='/')
            sta.push(sour[i]);
    }
    while(!sta.empty())
    {
        res[ind++] = sta.top();
        sta.pop();
    }
    for(int i=0;i<ind;++i)
        printf("%c",res[i]);
    return 0;
}

发布了61 篇原创文章 · 获赞 7 · 访问量 3629

猜你喜欢

转载自blog.csdn.net/weixin_42469716/article/details/104848033