深入解析前缀,中缀,后缀表达式

每次学习到数据结构中的“栈”的时候,都或多或少地会碰到前缀、中缀、后缀表达式的知识。然而,你是否有过这样的疑问: 符号栈里面,优先级大的在上面还是小的在上面来着?优先级是必须大于等于还是必须大于?虽然我知道怎么把中缀变后缀,但是为什么要这么变啊?额,每次学了会,会了忘,好苦恼啊! 本篇博客就带你一起揭开这些疑问,本篇博客不会机械化地告诉你具体如何操作,而是告诉你为什么要这么操作,原理在哪里。

一、熟其面才能见其理1. 我们首先来看一下,什么是前缀、中缀、后缀表达式:

中缀表达式: 后缀表达式: 前缀表达式:

PS:简单介绍下,前中后的划分依据为两个数字的操作符处于两个数字的前面,中间还是后面。其中,中缀表达式为我们日常生活中常见的表达形式。

2. 重要操作过程:

我们来一起回顾一下几个重要的操作过程。

后缀表达式求值过程:

从左到右扫描后缀表达式:遇到数字就将其压入栈中;遇到操作符,则取出栈顶的两个元素(栈顶元素为a,另一个为b。),并计算b 操作符 a的取值,并将结果重新压入栈中。扫描整个表达式结束后,栈中数值即为整个表达式的结果。

前缀表达式求值过程:

从右向左扫描前缀表达式:其他操作除了(栈顶元素为b,另一个为a。)与后缀表达式求值过程相同,不再赘述。

中缀表达式转换为后缀表达式过程:

从左向右扫描中缀表达式,遇到数字直接输出; 遇到操作符,就压入栈中,如果此时栈中已经存在操作符,则比较栈顶操作符和待压入操作符的优先级,如果待压入操作符的优先级高于栈顶操作符的优先级,则执行压栈操作。否则,弹出栈顶操作符并输出。 继续比较新的栈顶操作符和待压入操作符,直到将栈中所有操作符都弹出或待压入操作符的优先级大于栈顶操作符优先级。 扫描完毕后,如果栈里还存在操作符则将栈内所有操作符依次弹出并输出。最后得到的输出结果即为中缀表达式所对应的后缀表达式。

中缀表达式转换为前缀表达式过程:

从右向左扫描中缀表达式,遇到数字直接输出; 遇到操作符,除了将“待压入操作符的优先级高于栈顶操作符的优先级”改为“待压入操作符的优先级不低于栈顶操作符的优先级”外和“中缀变后缀的过程”相同。 扫描完毕,得到输出后,再将输出表达式左右对调,即为最后的结果。

二、深入解析,探究谜底。

在第一部分,我们一起简要回顾了一下前缀、中缀、后缀表达式的相关知识。就当一个热身运动。众所周知,虽然前缀表达式比后缀表达式出现的早,但是,现在较为常用的却是后缀表达式,所以,下面我们也主要以后缀表达式为例子。

谜题1: 中缀变后缀的过程中,为什么要保持栈中操作符的优先级从栈顶开始到栈底结束,优先级逐渐严格递减?

可能很多人都有这样的疑问:为什么待压入操作符的优先级必须大于栈顶操作符优先级,等于也不行,小于也不行,可能主要纠结于为什么等于不行!

谜题1解答:

要解答这个问题,首先要纠正一个我们平常所持有的惯用思维。我们一直认为:乘除优先级相同,加减优先级相同,且乘除大于加减。 其实,这是不准确的,准确来说,在一个表达式中没有任何两个优先级相等的操作符,比如:,其实,我们会先算乘法,再算除法。没错,这就是“从左到右”法则。 所以,其实“操作符存储栈”里面的操作符是严格遵循从栈顶到栈底,优先级逐次递减的。比如:,从左向右扫描到”/”号的时候,栈中状态为 号会弹出,然后将”/”号压入栈中。

另外,我们一直没有谈到有()的情况该怎么办,其实()会强制提高符号的优先级,比如:,当然了,当遇到)括号时,所有(括号之上的操作符必须强制弹出。

PS:同理,你可以想想为什么中缀变前缀的时候,就变成了不低于,而不是高于?记得它是从右向左扫描哦。

谜题2:中缀表达式和后缀表达式是不是有着某种奇妙的联系?我可不可以快速地将中缀表达式变换为后缀表达式?

在这里,我们为了简化问题的分析过程,我们将只考虑不存在括号的情况。

谜题2解答:

“投机取巧是成功的第一步”,不不!应该是:善于发现规律并利用规律提高效率的人,很Good!额,请原谅我的词穷。

有没有联系?这个肯定有。就是变个身嘛。我们从表面上可以看出来,中缀表达式和后缀表达式的数字排列顺序是完全相同的,只是符号的位置和顺序不太一样。

这不废话嘛!但是,正是这句废话,却是我们寻找快速转换的切入点。如果要实现快速转换,只需要快速确定操作符的位置和顺序,那么就大功告成了!

如何操作呢? 首先,将整个表达式分为许多连续的模块。这些模块是下面三种模式中的一种: 模式一: a b 。(其中,a,b为操作数。) 模式二:。(其中,a为操作数。) 模式三: 我们可以看到,上面前两种模式的操作符的优先级都是递增的。第二个模式,只有一个操作符,额,也就无所谓递增了。第三种模式较为特殊,以+/-符号开头,然后接下来是一连串的*或/符号。 划分原则为:有模式三就化模式三,有模式一就化模式一,最后考虑模式二。 然后,将模式一的式子变为:,将模式二的式子变为:,将模式三的式子改为:

实战练习:

转换为后缀表达式为:

到这里,前缀、中缀、后缀表达式的介绍就结束了,如果你还有什么疑问或者好的建议,欢迎留言,一起交流,一起讨论。

,孑然一身,隐入苍茫自然,自有一种孤独的意味;旅行,

深入解析前缀,中缀,后缀表达式

相关文章:

你感兴趣的文章:

标签云: