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. 给每一步表达式都加上括号。
    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))
  2. 将所有括号中的运算符提到括号之前。
    ( 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))
  3. 将括号全部去掉。
    这一步之后表达式变成 − + × + 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×

想让这个前缀表达式转为中缀,这里介绍括号法。

括号法

从左到右逐个比较
遇到连续两个表达式加一个运算符的组合
即将其转换为中缀,运算流程如下:

  1. ( a + b ) c × d + e g + h × − (a+b)c\times d+eg+h\times - (a+b)c×d+eg+h×
  2. ( ( a + b ) × c ) d + e g + h × − ((a+b)\times c)d+eg+h\times - ((a+b)×c)d+eg+h×
  3. ( ( ( a + b ) × c ) + d ) e g + h × − (((a+b)\times c)+d)eg+h\times - (((a+b)×c)+d)eg+h×
  4. ( ( ( a + b ) × c ) + d ) ( e + g ) h × − (((a+b)\times c)+d)(e+g)h\times - (((a+b)×c)+d)(e+g)h×
  5. ( ( ( a + b ) × c ) + d ) ( ( e + g ) × h ) − (((a+b)\times c)+d)((e+g)\times h)- (((a+b)×c)+d)((e+g)×h)
  6. ( ( ( ( a + b ) × c ) + d ) − ( ( e + g ) × h ) ) ((((a+b)\times c)+d)-((e+g)\times h)) ((((a+b)×c)+d)((e+g)×h))

最后去括号:

  1. ( 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

如果大家觉得对自己有帮助,欢迎点点关注,下期再见! 如果大家觉得对自己有帮助,欢迎点点关注,下期再见! 如果大家觉得对自己有帮助,欢迎点点关注,下期再见!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值