CSP初赛福音!前、中、后缀表达式互相转换的所有方法
前言
在这篇文章中,我将详尽的探讨不同的表达式的定义和互相转换的方法。
不同表达式的定义
前缀表达式:一种没有括号的表达式,与中缀表达式不同的是,将运算符写在前面,操作数写在后面。如:前缀表达式 − 1 + 2 3 -1+2\,\,\,3 −1+23 的中缀形式为 1 − ( 2 + 3 ) 1-(2+3) 1−(2+3)。
中缀表达式:与平常使用的表达式相同,有括号且运算符在操作数中间。
后缀表达式:与前缀表达式相反,将操作数写在前面,运算符写在后面。如:后缀表达式 1 2 3 + − 1\,\,\,2\,\,\,3+- 123+− 的中缀形式为 1 − ( 2 + 3 ) 1-(2+3) 1−(2+3)。
中缀to前缀 or 中缀to后缀
e.g. ( a + b ) × c + d − ( e + g ) × h (a+b)\times c+d-(e+g)\times h (a+b)×c+d−(e+g)×h
想让这个中缀表达式转为前缀 or 后缀,一般有 3 3 3 种方法。
括号法
想让这个中缀表达式转为后缀,步骤如下:
- 给每一步表达式都加上括号。
如 1 + 2 × 3 1+2\times 3 1+2×3 需要变成 ( 1 + ( 2 × 3 ) ) (1+(2\times 3)) (1+(2×3)) 。 (也就是一个括号中只能有一个运算符)
这一步之后表达式变成 ( ( ( ( a + b ) × c ) + d ) − ( ( e + g ) × h ) ) ((((a+b)\times c)+d)-((e+g)\times h)) ((((a+b)×c)+d)−((e+g)×h)) 。 - 将所有括号中的运算符提到括号之前。
如 ( 1 + ( 2 × 3 ) ) (1+(2\times 3)) (1+(2×3)) 需要变成 + ( 1 × ( 23 ) ) +(1\times (23)) +(1×(23)) 。
这一步之后表达式变成 − ( + ( × ( + ( a b ) c ) d ) × ( + ( e g ) h ) ) -(+(\times (+(ab)c)d)\times (+(eg)h)) −(+(×(+(ab)c)d)×(+(eg)h)) 。 - 将括号全部去掉。
这一步之后表达式变成 − + × + a b c d × + e g h -+\times +abcd\times +egh −+×+abcd×+egh ,这就是最终的表达式
想要变成前缀只需要将第 2 2 2 步 “将所有括号中的运算符提到括号之前” 变成 “将所有括号中的运算符提到括号之后”。
表达式树法
关于这一部分,需要预先掌握这 2 2 2 个知识点:
- 二叉树的相关定义
- 二叉树的遍历
其中若有任一没有掌握,推荐大家先看看这篇文章。
表达式树是一种特殊的二叉树,它的叶节点是操作数,其余节点是运算符。我们可以借助表达式树转换前中后缀表达式。
在这个问题中,我们首先把 ( a + b ) × c + d − ( e + g ) × h (a+b)\times c+d-(e+g)\times h (a+b)×c+d−(e+g)×h 转换为表达式树:
然后先序遍历这棵树即可得到 − + × + a b c d × + e g h -+\times +abcd\times +egh −+×+abcd×+egh 。
这对熟悉二叉树的同学非常友好。
入栈法
比较适用于中缀to后缀
这个方法需要准备一个栈,并将字符一个个压入栈中 or pop出栈,栈中的元素都有一个优先级。
来看看如何入栈:
- 如果符号为
运算数
:
直接送入后缀表达式(需要先分析出完整的运算数)。 - 如果字符为
左括号
:
直接入栈,优先级最低。 - 如果字符为
右括号
:
直接出栈,并将栈中字符依次出栈并送入后缀表达式,直到栈顶字符为左括号(左括号也要出栈,但不送入后缀表达式)。 - 如果字符为
操作符
:
只要满足栈空
或者优先级高于栈顶操作符
即可停止出栈,并将该操作符入栈。
前缀to中缀 or 后缀to中缀
e.g. 前缀表达式 a b + c × d + e g + h × − ab+c\times d+eg+h\times - ab+c×d+eg+h×−
想让这个前缀表达式转为中缀,这里介绍括号法。
括号法
从左到右逐个比较
遇到连续两个表达式加一个运算符的组合
即将其转换为中缀,运算流程如下:
- ( a + b ) c × d + e g + h × − (a+b)c\times d+eg+h\times - (a+b)c×d+eg+h×−
- ( ( a + b ) × c ) d + e g + h × − ((a+b)\times c)d+eg+h\times - ((a+b)×c)d+eg+h×−
- ( ( ( a + b ) × c ) + d ) e g + h × − (((a+b)\times c)+d)eg+h\times - (((a+b)×c)+d)eg+h×−
- ( ( ( a + b ) × c ) + d ) ( e + g ) h × − (((a+b)\times c)+d)(e+g)h\times - (((a+b)×c)+d)(e+g)h×−
- ( ( ( a + b ) × c ) + d ) ( ( e + g ) × h ) − (((a+b)\times c)+d)((e+g)\times h)- (((a+b)×c)+d)((e+g)×h)−
- ( ( ( ( a + b ) × c ) + d ) − ( ( e + g ) × h ) ) ((((a+b)\times c)+d)-((e+g)\times h)) ((((a+b)×c)+d)−((e+g)×h))
最后去括号:
- ( a + b ) × c + d − ( e + g ) × h (a+b)\times c+d-(e+g)\times h (a+b)×c+d−(e+g)×h
( a + b ) × c + d − ( e + g ) × h (a+b)\times c+d-(e+g)\times h (a+b)×c+d−(e+g)×h 就是最终答案了。
后缀to中缀大同小异
后缀to前缀 or 前缀to后缀
这里介绍 2 2 2 种方法。
括号法
与上述过程相似,先用括号标注,随后将后缀的运算符移到前面(反之亦然)。
表达式树法
将后缀变为表达式树,随后将表达式树转换为前缀表达式(反之亦然)。
后序
参考文献(排名不分先后):
- https://blog.csdn.net/Amentos/article/details/127182926
- https://blog.csdn.net/qq_40877281/article/details/115824864
- https://www.luogu.com.cn/blog/334586/csp-pre-knowledge
如果大家觉得对自己有帮助,欢迎点点关注,下期再见! 如果大家觉得对自己有帮助,欢迎点点关注,下期再见! 如果大家觉得对自己有帮助,欢迎点点关注,下期再见!