波兰式和逆波兰式

       前缀、中缀、后缀表达式是对表达式的不同记法,其区别在于运算符相对于操作数的位置不同,前缀表达式的运算符位于操作数之前.

       中缀和后缀同理虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单

举例:
中缀表达式:1 + (2 + 3) × 4 - 5
前缀表达式:- + 1 × + 2 3 4 5
后缀表达式:1 2 3 + 4 × + 5 -

波兰式

什么是波兰式?

将操作符号写在操作数之前,也就是前缀表达式

中缀转前缀转换过程同样需要用到栈,具体过程如下:
将中缀表达式转换为前缀表达式:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从右至左扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:

  • (4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈
  • (4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1
  • (4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;

前缀表达式的计算机求值

  1. 从右至左扫描表达式
  2. 遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈
  3. 重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果

计算前缀表达式的值:- + 1 × + 2 3 4 5

  1. 从右至左扫描,将5,4,3,2压入堆栈;
  2. 遇到+运算符,弹出2和3(2为栈顶元素,3为次顶元素),计算2+3的值,得到5,将5压入栈;
  3. 遇到×运算符,弹出5和4,计算5×4的值,得到20,将20压入栈;
  4. 遇到1,将1压入栈;
  5. 遇到+运算符,弹出1和20,计算1+20的值,得到21,将21压入栈;
  6. 遇到-运算符,弹出21和5,计算21-5的值,得到16为最终结果

逆波兰表达式

什么是逆波兰表达式?

转换规则

  1)我们使用一个stack栈结构存储操作符,用一个List结构存储后缀表达式结果

  2)首先读取到数字,直接存入list中

  3)当读取到左括号"("时,直接压栈,当读取到运算符时,分两种情况讨论

    a.当运算符栈为空或者栈顶操作符的优先级小于当前运算符优先级时(如+和-的优先级低于 * 和 /),直接入栈

    b.当运算符不为空时且栈顶操作符的优先级大于或等于当前运算符优先级时,循环执行出栈操作并加入list中,直到遇到优先级小于当前运算符的元素为止。循环执行完后再将当前运算符压栈。另外需要注意的是,只有遇到右括号时,左括号才出栈

  4) 当遇到右括号")"时,循环执行出栈操作并加入到list中,直到遇到左括号为止。并将左括号弹出,但不加入list中

  5) 表达式的值读取完后,将操作符栈中的所有元素弹出并加入到list中

  执行完上面步骤后,list中存储的顺序即为我们转换后的后缀表达式的结果

转换实例

运算符在操作数的后面 3 * 4 ===> 3 4 *, 所以也被称为后缀表达式。

使用逆波兰表达式时,是不需要使用括号的。在中缀表达式中,例如:(3 - 4) * 5,我们需要使用括号提高减号的优先级,而在逆波兰表达式中是不需要使用括号的,3 4 - 5 * ,直接在3 4操作数后面跟着一个-号, 就可以表示3 - 4是首先计算的。

再举几个例子:

  • 3 - 4 * 5 ===> 3 4 5 * -
  • (4 + (13 / 5)) ===> 4 13 5 / +
  • ((2 + 1) * 3) = 9 ===> 2 1 + 3 *

手动计算逆波兰表达式

面对一个复杂逆波兰表达式,我们改如何计算呢?

例如:10 6 9 3 + -11 * / * 17 + 5 +

我们首先从头开始遍历逆波兰表达式字符串

  1. 遇到第一个 +9 + 3 = 12,现在的表达式是,10 6 12 -11 * / * 17 + 5 +
  2. 遇到第二个 *12 * -11 = -132,现在的表达式是 10 6 -132 / * 17 + 5 +
  3. 遇到第三个 /6 / -132 = -0.04,现在的表达式 10 -0.04 * 17 + 5 +
  4. 遇到第四个 *10 * -0.04 = -0.4,现在的表达式 -0.4 17 + 5 +
  5. 遇到第五个 +-0.4 + 17 = 16.6,现在的表达式 16.6 5 +
  6. 遇到第六个 +16.6 + 5 = 21.6

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中将表达式转化为波兰式逆波兰式的方法是使用栈来实现。波兰式(前缀式)指的是运算符号位于其对应的操作数之前,而逆波兰式(后缀式)指的是运算符号位于其对应的操作数之后。 将中缀表达式转换为前缀或后缀表达式可以通过以下步骤进行: 1. 创建一个符号栈(Stack)和一个结果队列(Queue)。 2. 从左到右扫描中缀表达式,若遇到操作数,将其加入到结果队列中。 3. 若遇到运算符,比较其与栈顶运算符的优先级,若优先级低于栈顶元素,则将栈顶元素弹出并加入到结果队列中,直接层层递进,直到遇到比该元素优先级较低的元素为止。 4. 若遇到左括号“(”,则将其入栈。 5. 若遇到右括号“)”,则依次弹出栈顶元素,加入到结果队列中,直到左括号“(”被弹出。注意:左括号“(”不加入到结果队列中。 6. 最后,如果符号栈中仍有元素,则依次弹出加入到结果队列中。 7. 若要将中缀表达式转换逆波兰式,则将符号栈改为栈,并将操作数加入到栈中。 8. 遇到运算符时,弹出栈顶的两个操作数进行计算,并将结果压入栈中。 9. 最后栈中仅剩一个元素,即为逆波兰式。 注意事项: 在将中缀表达式转换为前缀表达式时,我们需要先将中缀表达式翻转,再按照转换成后缀表达式的方法进行。 在计算逆波兰式时,需要注意操作数的顺序,因为后缀式在操作数的顺序上没有明确的要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值