Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算

中缀表达式与后缀表达式的转换和计算



目录

  1. 中缀表达式转换为后缀表达式
  2. 后缀表达式的计算

中缀表达式转换为后缀表达式

中缀表达式转换为后缀表达式的实现方式为:

  1. 依次获取中缀表达式的元素,
  2. 若元素为操作数(数字/字母等),则加入后缀表达式中
  3. 若元素为操作符,则压入栈中,此时对比入栈操作符与栈内元素的计算等级,等级大于或等于入栈元素的栈内操作符都将被弹出栈,加入到后缀表达式中
  4. 左括号直接入栈,优先级最高,不弹出栈内元素
  5. 右括号不入栈,而是弹出所有元素加入后缀表达式,直至遇见匹配的左括号,并弹出左括号但不加入后缀表达式中
  6. 当中缀表达式的元素耗尽后,依次弹出栈内元素加入到后缀表达式中。

代码实现过程如下,

完整代码

 1 from linked_list_stack import Stack
 2
 3 SIGN = {‘+‘: 1, ‘-‘: 1, ‘*‘: 2, ‘/‘: 2, ‘(‘: 3}
 4
 5
 6 def infix_to_postfix(expr):
 7     global SIGN
 8     out = []
 9     s = Stack()
10     for i in expr:
11         if i in SIGN.keys():
12             # Pop all high level sign except left bracket
13             while s.top():
14                 if SIGN[s.top()] < SIGN[i] or s.top() == ‘(‘:
15                     break
16                 out.append(s.pop())
17             # Push sign
18             s.push(i)
19         elif i == ‘)‘:
20             # Pop all sign until left bracket encountered
21             while s.top() != ‘(‘:
22                 out.append(s.pop())
23             # Pop left bracket
24             s.pop()
25         else:
26             # Push number
27             out.append(i)
28
29     while s.top():
30         out.append(s.pop())
31     return out
32
33
34 if __name__ == ‘__main__‘:
35     ep = ‘a + b * c + ( d * e + f ) * g‘
36     print(‘ ‘.join(infix_to_postfix(ep.split(‘ ‘))))

分段解释

首先从链表栈中导入栈类,并定义各个操作符的优先级

1 from linked_list_stack import Stack
2
3 SIGN = {‘+‘: 1, ‘-‘: 1, ‘*‘: 2, ‘/‘: 2, ‘(‘: 3}

接着定义转换函数,

  1. 函数接受一个中缀表达式的可迭代对象,创建列表out存放后缀表达式,以及一个空栈s
  2. 随后开始遍历中缀表达式,判断遍历元素的类型,若为操作数则加入out,
  3. 若为右括号则依次弹出栈内元素加入out列表,直到遇见左括号,弹出左括号不加入out,
  4. 若为普通操作符则压入栈中,并对比栈内操作符优先级,依次弹出高优先级或相同优先级的操作符,
  5. 遍历结束后依次弹出栈内元素,最后返回后缀表达式的字符串形式。
 1 def infix_to_postfix(expr):
 2     global SIGN
 3     out = []
 4     s = Stack()
 5     for i in expr:
 6         if i in SIGN.keys():
 7             # Pop all high level sign except left bracket
 8             while s.top():
 9                 if SIGN[s.top()] < SIGN[i] or s.top() == ‘(‘:
10                     break
11                 out.append(s.pop())
12             # Push sign
13             s.push(i)
14         elif i == ‘)‘:
15             # Pop all sign until left bracket encountered
16             while s.top() != ‘(‘:
17                 out.append(s.pop())
18             # Pop left bracket
19             s.pop()
20         else:
21             # Push number
22             out.append(i)
23
24     while s.top():
25         out.append(s.pop())
26     return out
27
28
29 if __name__ == ‘__main__‘:
30     ep = ‘a + b * c + ( d * e + f ) * g‘
31     print(‘ ‘.join(infix_to_postfix(ep.split(‘ ‘))))

最后可以得到表达式输出结果为

a b c * + d e * f + g * +

2 后缀表达式的计算

后缀表达式的计算过程其实也是后缀转换为中缀的一个过程:

  1. 首先依次遍历后缀表达式,
  2. 当元素为操作数时,压入栈中,
  3. 当元素为操作符时,弹出栈内最顶上的两个元素,进行操作运算,将得到的结果再次压入栈中,
  4. 直到后缀表达式遍历结束,此时栈内只有唯一的一个元素即最终的运算结果,弹出栈即可

实现的过程十分简单,具体代码如下,其中中缀表达式转后缀表达式的方法为前面定义的方法

完整代码

 1 from linked_list_stack import Stack
 2
 3 SIGN = {‘+‘: 1, ‘-‘: 1, ‘*‘: 2, ‘/‘: 2, ‘(‘: 3}
 4
 5
 6 def postfix_calc(expr):
 7     global SIGN
 8     s = Stack()
 9     for i in expr:
10         if i in SIGN.keys():
11             right = str(s.pop())
12             left = str(s.pop())
13             cal = ‘ ‘.join((left, i, right))
14             # cal = ‘ ‘.join([str(s.pop()), i, str(s.pop())][::-1])
15             s.push(eval(cal))
16         else:
17             s.push(i)
18     return s.pop()
19
20 if __name__ == ‘__main__‘:
21     ep = ‘( ( 2 + 3 ) * 8 + 5 + 3 ) * 6‘
22     print(eval(ep))
23     print(postfix_calc(infix_to_postfix(ep.split(‘ ‘))))
24
25     ep = ‘3 + ( 2 * 9 ) / 2 * ( 3 + 6 ) * 7‘
26     print(eval(ep))
27     print(postfix_calc(infix_to_postfix(ep.split(‘ ‘))))  

最后测试直接运算中缀表达式和中缀转后缀后再计算得到的结果,两者结果相同。

288
288
570.0
570.0

原文地址:https://www.cnblogs.com/stacklike/p/8284594.html

时间: 2024-08-11 01:32:15

Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算的相关文章

数据结构——栈——中缀表达式和后缀表达式

什么是中缀表达式,什么是后缀表达式 我们一般看见的多项式计算都是中缀表达式构成的:1+2*3+4/3 类似这种,为什么说是中缀呢?因为它的计算符号都是在两个数中间的. 那么自然而然的明白了后缀表达式是一种计算符号在两个数后面的. 如123*+43/+ 中缀表达式和后缀表达式有什么关系? 其实仔细你就会发现,上面给出的式子其实都是一样的,只是计算的顺序在后缀表达式中你看不懂而已. 因为我们习惯去看中缀表达式的计算. 其实他们之间是可以互相转换的.他们也可以表达同一个意思,同一个计算式子. 为什么会

栈的应用之中缀表达式转后缀表达式

1,中缀表达式的定义及为什么要将中缀表达式转换为后缀表达式? 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间.中缀表达式是人们常用的算术表示方法. 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值.对计算机来说,计算前缀或后缀表达式的值要比中缀表达式简单. 比如,计算机计算后缀表达式的过程如下----后缀表达式的计算机求值: 从左

数据结构中缀表达式转后缀表达式以及后缀转中缀表达式

最近一直在看数据结构这本书,我相信,对于每个程序员来说,数据结构都尤为重要.为什么要学,可以看看这位博友的认识http://blog.csdn.NET/sdkfjksf/article/details/54380659 直入主题:将中缀表达式转为后缀表达式 以及将后缀表达式转为前缀表达式的实现. 关于后缀转中缀,中缀转后缀的理论介绍,请先阅读其互转的理论知识,或者我转发的这篇文章,这里不再累赘,最好参考<数据结构与算法描述Java语言版>,接下来将会用java写. 一.首先,怎么实现中缀表达式

将中缀表达式转换为后缀表达式,然后利用栈对表达式求值。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js.js"></script> </head> <body> 输入中缀表达式空格分隔 例如 2 + 3 <input type=

栈的应用 — 中缀式转后缀式

由中缀式转换成后缀式,同样使用栈,并运用一些规则来完成.规则介绍如下: 当读到的是操作数,立即输出. 当读到的是运算符,则先从栈中弹出优先级高于自己的运算符(不包含括号),自己入栈. 读到左括号入栈,读到右括号则将栈中元素出栈并输出,直到遇见左括号(括号都不输出). 输入为空后,将栈元素弹出并输出直到栈空. 注意,最后生成的后缀表达式是考虑了运算符优先级的,再配合逆波兰的无优先级概念这一性质,就能够编写出一个带运算符优先级和括号的简易计算器了. 下面是完整的计算器代码,整型四则运算,可加括号.写

栈的应用:中缀表达式转为后缀表达式

1.中缀表达式转为后缀表达式 规则:(栈实现) 1)如果遇到操作数,我们就直接将其输出. 2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中. 3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止.注意,左括号只弹出并不输出. 4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止.弹出完这些元素后,才将遇到的操作符压入到栈中.有一点需要注意,只有在遇到" ) "的情况下

数据结构Java实现06----中缀表达式转换为后缀表达式

数据结构Java实现06----中缀表达式转换为后缀表达式 本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *.又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符

中缀表达式与后缀表达式

计算中缀表达式"可以称得上是一个特别经典的关于栈的算法题,几乎在所有数据结构教材中都会涉及,而且很多公司面试或者笔试的时候都会把这道题作为一个考察点.可以说,这是一道必须要掌握的算法题.中缀表达式.后缀表达式等概念在这里就不赘述了,让我们直奔主题.题目:输入一个中缀表达式,计算其结果.输入的前提假设:(1)只考虑+.-.*./这四种运算符,中缀表达式中只有一种括号:():(2)输入的中缀表达式中只有整数,没有小数:(3)假定输入是合法的.很多文章或课本喜欢一步到位,直接讨论如何从中缀表达式计算结

中缀表达式转为后缀表达式

** * 中缀表达式转后缀表达式 * * 作用:将一长串计算表达式转换为计算机易于操作的字符序列,用于计算器的设计 *  * 参与转换运算符 * +-/*()^% * * * 使用StringBuilder来保存转换出的后缀表达式 * 使用栈来操作运算符 * * * 转换原则 * 1.上述字符中()没有优先级值,+-优先级值为1,/*%优先级值为2,^优先级值为3 * 2.对于一个待计算的表达式,从左向右逐个检查每个字符 * 3.遇到数字,直接append到StringBuilder * 4.遇