java利用栈求复杂表达式_如何用栈求表达式的值?(超级详细)

本文介绍了如何使用栈结构求解后缀表达式的值,详细阐述了后缀表达式的概念和求值过程。通过波兰逻辑学家J・卢卡西维兹提出的后缀表达式,我们可以抛弃括号和运算优先级,转而借助栈来轻松求解表达式的值。文章还提供了具体的转换和计算方法,包括调用场算法将普通表达式转换为后缀表达式,并给出了相应的C语言实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过前面章节的学习,读者已经了解了什么是栈以及栈存储结构的 2 种实现方式(顺序栈和链栈)。在此基础上,本节教读者用栈解决一个实际问题:如何用栈结构求一个表达式的值?

所谓表达式,就是由变量、常量以及运算符组合而成的式子。其中,常用的运算符无非 !(阶乘运算符)、^(指数运算符)、+、-、*、/ 、( ) 这几种,比如3!+4*2/(1-5)^2就是一个表达式。

那么,如何用栈结构求一个表达式的值呢?实际上,已经有前辈设计好了一种完美的解决方案。

1929 年,波兰逻辑学家 J・卢卡西维兹提出了一种全新的表示表达式的方法,称为后缀表达式或者逆波兰表达式。和普通表达式不同,后缀表达式习惯将运算符写在它的运算项之后,且整个表达式中不用括号 () 表明运算的优先级关系。

以 3! 为例,! 为 运算符,3 为运算项,因此 3! 本身就是一个后缀表达式;再以 4*2 为例,* 为运算符,4 和 2 作为它的运算项,其对应的后缀表达式为 4 2+。

在此基础上,我们试着将 3!+4*2/(1-5)^2 转换成后缀表达式,其过程也就是将表达式中所有运算符放置在它的运算项之后:

! 运算符对应的运算项为 3,转换后得到3 !;

+ 运算符对应的运算项是 3! 和 4*2/(1-5)^2,转换之后得到:3! 4*2/(1-5)^2 +;

* 运算符对应的运算项是 4 和 2,转换之后得到4 2 *;

/ 运算符对应的运算项是 4 2 * 和 (1-5)^2,转换后得到4 2 * (1-5)^2 /;

- 运算符对应的运算项是 1 和 5,转换后得到1 5 -;

^ 运算符对应的运算项是 1 5 - 和 2 ,转换后得到1 5 - 2 ^。

整合之后,整个普通表达式就转换成了3 ! 4 2 * 1 5 - 2 ^ / +,这就是其对应的后缀表达式。

不难发现,后缀表达式完全舍弃了表达式本该有的可读性,但有失必有得,相比普通表达式,后缀表达式的值可以轻松借助栈存储结构求得。具体求值的过程是:当用户给定一个后缀表达式时,按照从左到右的顺序依次扫描表达式中的各个运算项和运算符,对它们进行如下处理:

遇到运算项时,直接入栈;

遇到运算符时,将位于栈顶的运算项出栈,对于 ! 运算符,取栈顶 1 个运算项;其它运算符,取栈顶 2 个运算项,第一个取出的运算项作为该运算符的右运算项,另一个作为左运算项。求此表达式的值并将其入栈。

经过以上操作,直到栈中仅存在一个运算项为止,此运算项即为整个表达式的值。

以3 ! 4 2 * 1 5 - 2 ^ / +表达式为例,求值的过程为:

1) 从 3 开始,它是运算项,因此直接入栈:

af249d64d6ec226589c0b16467b1d811.gif

2) ! 作为运算符,从栈顶取 1 个运算项(也就是 3),求 3! 的值(3! = 3*2*1=6)并将其入栈:

0ababbf1c478163d9b59e6c26b482c03.gif

3) 将 4 和 2 先后入栈:

bd9a80133f69662ea28c5a198ede4861.gif

4) 对于 * 运算符,取栈顶 2 个运算项( 2 和 4),其中先取出的 2 作为 * 的右操作数,4 作为左操作数。求的 4* 2 的值 8 ,并将其入栈:

192f9a9629d641ad1a1984c43e7a367a.gif

5) 将 1 和 5 先后入栈:

c543934aac64727247e4640be5f8a89b.gif

6) 对于 - 运算符,取栈顶 2 个运算项(5 和 1),计算出 1-5 的值为 -4,将其入栈:

c663baad1a7e5f5c0ef8233302f508fa.gif

7) 将 2 入栈:

ce35e56a637b1e3b42c29fb7c45a980a.gif

8) 对于 ^ 运算符,取栈顶 2 个运算项(2 和 -4),计算出 -4^2 的值 16 ,将其入栈:

5f09b8656c508d5c6f6360518217db40.gif

9) 对于 / 运算符,取栈顶 2 个运算项(16 和 8),计算出 8/16 的值 0.5,将其入栈:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值