前言
众所周知,我们平常用的表达式都是中缀表达式,其中,有一个十分重要的存在——括号。但是,在计算机开始的时候并没有括号,那么该怎么判定优先级呢?这就要说到后缀表达式了。
正文
后缀表达式,又称逆波兰式,是更接近于系统底层栈的表示方法。相比于中缀表达式,计算机更容易理解后缀表达式。但是对于人类来说,后缀表达式并没有那么好理解 (但也不是太难)。
一般来说,后缀表达式使用栈来模拟。
得出后缀表达式的答案
后缀表达式的答案方法很简单:从左往右开始读,读到数字,放着不动(压入栈中);读到运算符号把前两个数(一定是从左往右,也就是栈顶元素)拿运算符运算,再把两个数擦去(弹出),将答案存进去(压栈)。
代码:
#include <iostream>
#include <cctype>
#include <string>
#include <stdexcept>
using namespace std;
struct stack
{
int stk[100010];
int t=0;
void push(int x)
{
stk[t]=x;
++t;
}
bool empty()
{
if (t==0)
{
return true;
}
return false;
}
int pop()
{
int kkk=-32767;
try
{
if (empty()==true)
{
throw runtime_error("Runtime Error:Try to \"pop\" the top element of stack when the stack is empty.");
}
else
{
kkk=stk[t-1];
--t;
}
}
catch (runtime_error err)
{
cerr<<err.what()<<'\n';
}
return kkk;
}
int top()
{
int kkk=-32767;
try
{
if (empty()==true)
{
throw runtime_error("Runtime Error:Try to access the top element of stack when the stack is empty.");
}
else
{
kkk=stk[t-1];
}
}
catch (runtime_error err)
{
cerr<<err.what()<<'\n';
}
return kkk;
}
int size()
{
return t;
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
string str;
stack stk;
getline(cin,str);
int v=0;
bool flag=false;
for (auto i:str)
{
if (flag==true&&i==' ')
{
stk.push(v);
v=0;
flag=false;
continue;
}
if (isdigit(i))
{
flag=true;
v*=10;
v+=(static_cast<int>(i-'0'));
}
else if (i=='+'||i=='-'||i=='*'||i=='/')
{
int a=stk.top();
stk.pop();
int b=stk.top();
stk.pop();
int ans=0;
switch (i)
{
case '+':
ans=b+a;
break;
case '-':
ans=b-a;
break;
case '*':
ans=b*a;
break;
case '/':
ans=b/a;
break;
}
stk.push(ans);
}
}
cout<<stk.top()<<'\n';
stk.pop();
try
{
if (stk.empty()==false)
{
throw logic_error("Error!\n");
}
}
catch (logic_error err)
{
cout<<err.what();
return -1;
}
return 0;
}
将中缀表达式转换为后缀表达式
详见百度百科。
例子:
第 9 题
表达式 a ∗ ( b + c ) ∗ d a*(b+c)*d a∗(b+c)∗d 的后缀表达式为( ),其中 ∗ * ∗ 和 + + + 是运算符。
A. ∗ ∗ a + b c d **a+bcd ∗∗a+bcd
B. a b c + ∗ d ∗ abc+*d* abc+∗d∗
C. a b c + d ∗ ∗ abc+d** abc+d∗∗
D. ∗ a ∗ + b c d *a*+bcd ∗a∗+bcd
参考资料
文章
本文参考了OI Wiki - 杂项 - 表达式求值。OI Wiki文章的版权协议为CC BY-SA 4.0 和 SATA 协议。例子与简略答案来自洛谷有题 CSP 2021 入门级第一轮与计蒜客 2021 CSP-J1 入门级第一轮。