- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
解析算术表达式
解析算术表达式[1]后缀式(逆波兰式)
HYPERLINK http://blueve.me/archives/318 六212011
293
HYPERLINK http://blueve.me/archives/318 \l respond \o 《解析算术表达式[1]后缀式(逆波兰式)》上的评论 Leave a Comment Written by HYPERLINK http://blueve.me/archives/author/blueve \o View all posts by Blueve Blueve
后缀(postfix, 也成逆波兰 reverse Polish)表达式在我们的生活中并不常见,在我们日常中见到的,通常都是中缀(infix)式,例如:
3.14 + 15 * (9.2 – 6.5)
这是便于人类理解的表达式,之所以便于人类理解,是因为人从小便接受识别此类表达式的教育,而且这种记号方式将运算符和数字明确的分开,不会产生数字堆叠在一起的混乱情况。但是对于计算机而言,这样的表达式并不好理解,计算机是一种线性读入信息,线性输出信息的工具,人类所通识的中缀式,对于这种规规矩矩按照顺序计算的工具而言,是不容易理解的。你可能一眼就看出来要先算小括号里的表达式,然后算乘法,最后算加法。而计算机直接读入的话,可能会先算3.14 + 15,这自然是荒谬的,而后缀法就为计算机计算表达式提供了一种非常有效的解决方案。这篇文章主要的内容是介绍如何将中缀表达式转换为后缀表达式。说了这么半天,后缀表达式又是什么样子呢?它又有什么样的优势呢?我们现在来看一组对比:
中缀式
后缀式
a + b
a b +
a + b * c
a b c * +
(a + b) * c
a b + c *
后缀表达式为什么会有优势呢?因为计算机线性读入的特征,我们以第二个表达式为例,以:用后缀式,在计算机的计算过程就是:
a
a b
a b c
a b c *
a (b * c) 计算出b * c的值记作x
a x +
(a + x) 计算出a + x 的值
就是这样一个符合线性读入过程的运算,这样就合理的解决了运算之间优先关系的处理。那么如何将一个中缀式装换为后缀式呢?其实算法很简单,运用之前我介绍过的“栈”就可以轻易达到这个目的,我们使用两个栈,一个是表达式栈,用来存储转换成后缀表达式的结果,一个是运算符栈,用来暂存表达式中的运算符,这个栈满足条件“从栈顶到栈底,运算符的优先级依次下降”,我们以表达式a + b * (c + d) 作为例子,来模拟一下转换的过程:
1.读入数字a,存入表达式栈,紧接着读入运算符+,存入运算符栈
2.读入数字b,存入表达式栈,紧接着读入运算符*,由于*比+运算优先级高,所以也可以存入运算符栈
3.读入左括号(,(具有最高优先级,所以也存入运算符栈,后面的数字c存入表达式栈
4.读入运算符+,存入运算符栈,然后读入数字d,存入表达式栈
5.读入右括号),开始弹出运算符栈中的运算符到表达式栈,直到遇到左括号为止
6.表达式已经读完了,将运算符栈中的运算符全部弹出到表达式栈,至此后缀表达式已经转换完成!
总结下来,基本步骤很明确,就是以下几个步骤:
(1)读入,如果是数字,就置入表达式栈,然后重复(1)。如果是运算符继续(2)如果是’)’,则将运算符栈中直到’(‘之前的运算符都弹入表达式栈,并弹出’(‘。否则继续(3)与运算符栈中的栈顶表达式比较,优先级高的话,置入运算符栈。否则将栈内的低优先级运算符弹入表达式栈,然后将新的运算符置入表达式栈。继续(4)如果所有的字符都已经读入完成,则将运算符栈中的符号全部弹入表达式栈,至此完成转换。否则,回到步骤(1)。
有了这样的算法思路,实现起来那就是非常容,易的事情了。下面给出我写的转换代码,需要注意,我的代码没有处理负号这样的情况,而且对于非法的表达式(比如括号不匹配,两个乘号在一起)也没有进行识别,所以在实用性上还是有所欠缺的。代码中通过一点简单的方法使得输入表达式的数字可以是浮点型的,表达式以字符串型栈保存,方便以后转换为数字。以下为代码:
HYPERLINK http://blueve.me/archives/318 \l # ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
文档评论(0)