Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算
中缀表达式与后缀表达式的转换和计算
目录
1 中缀表达式转换为后缀表达式
中缀表达式转换为后缀表达式的实现方式为:
- 依次获取中缀表达式的元素,
- 若元素为操作数(数字/字母等),则加入后缀表达式中
- 若元素为操作符,则压入栈中,此时对比入栈操作符与栈内元素的计算等级,等级大于或等于入栈元素的栈内操作符都将被弹出栈,加入到后缀表达式中
- 左括号直接入栈,优先级最高,不弹出栈内元素
- 右括号不入栈,而是弹出所有元素加入后缀表达式,直至遇见匹配的左括号,并弹出左括号但不加入后缀表达式中
- 当中缀表达式的元素耗尽后,依次弹出栈内元素加入到后缀表达式中。
代码实现过程如下,
完整代码
from linked_list_stack import Stack
SIGN = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3}
def infix_to_postfix(expr):
global SIGN
out = []
s = Stack()
for i in expr:
if i in SIGN.keys():
# Pop all high level sign except left bracket
while s.top():
if SIGN[s.top()] < SIGN[i] or s.top() == '(':
break
out.append(s.pop())
# Push sign
s.push(i)
elif i == ')':
# Pop all sign until left bracket encountered
while s.top() != '(':
out.append(s.pop())
# Pop left bracket
s.pop()
else:
# Push number
out.append(i)
while s.top():
out.append(s.pop())
return out
if __name__ == '__main__':
ep = 'a + b * c + ( d * e + f ) * g'
print(' '.join(infix_to_postfix(ep.split(' '))))
分段解释
首先从链表栈中导入栈类,并定义各个操作符的优先级
from linked_list_stack import Stack
SIGN = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3}
接着定义转换函数,
- 函数接受一个中缀表达式的可迭代对象,创建列表out存放后缀表达式,以及一个空栈s
- 随后开始遍历中缀表达式,判断遍历元素的类型,若为操作数则加入out,
- 若为右括号则依次弹出栈内元素加入out列表,直到遇见左括号,弹出左括号不加入out,
- 若为普通操作符则压入栈中,并对比栈内操作符优先级,依次弹出高优先级或相同优先级的操作符,
- 遍历结束后依次弹出栈内元素,最后返回后缀表达式的字符串形式。
def infix_to_postfix(expr):
global SIGN
out = []
s = Stack()
for i in expr:
if i in SIGN.keys():
# Pop all high level sign except left bracket
while s.top():
if SIGN[s.top()] < SIGN[i] or s.top() == '(':
break
out.append(s.pop())
# Push sign
s.push(i)
elif i == ')':
# Pop all sign until left bracket encountered
while s.top() != '(':
out.append(s.pop())
# Pop left bracket
s.pop()
else:
# Push number
out.append(i) while s.top():
out.append(s.pop())
return out if __name__ == '__main__':
ep = 'a + b * c + ( d * e + f ) * g'
print(' '.join(infix_to_postfix(ep.split(' '))))
最后可以得到表达式输出结果为
a b c * + d e * f + g * +
2 后缀表达式的计算
后缀表达式的计算过程其实也是后缀转换为中缀的一个过程:
- 首先依次遍历后缀表达式,
- 当元素为操作数时,压入栈中,
- 当元素为操作符时,弹出栈内最顶上的两个元素,进行操作运算,将得到的结果再次压入栈中,
- 直到后缀表达式遍历结束,此时栈内只有唯一的一个元素即最终的运算结果,弹出栈即可
实现的过程十分简单,具体代码如下,其中中缀表达式转后缀表达式的方法为前面定义的方法
完整代码
from linked_list_stack import Stack
SIGN = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3}
def postfix_calc(expr):
global SIGN
s = Stack()
for i in expr:
if i in SIGN.keys():
right = str(s.pop())
left = str(s.pop())
cal = ' '.join((left, i, right))
# cal = ' '.join([str(s.pop()), i, str(s.pop())][::-1])
s.push(eval(cal))
else:
s.push(i)
return s.pop()
if __name__ == '__main__':
ep = '( ( 2 + 3 ) * 8 + 5 + 3 ) * 6'
print(eval(ep))
print(postfix_calc(infix_to_postfix(ep.split(' '))))
ep = '3 + ( 2 * 9 ) / 2 * ( 3 + 6 ) * 7'
print(eval(ep))
print(postfix_calc(infix_to_postfix(ep.split(' '))))
最后测试直接运算中缀表达式和中缀转后缀后再计算得到的结果,两者结果相同。
288
288
570.0
570.0
Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算的更多相关文章
- Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现
栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...
- C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611
09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...
- 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放
01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...
- 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现
#!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...
- 中缀表达式得到后缀表达式(c++、python实现)
将中缀表达式转换为后缀表达式的算法思想如下: 从左往右开始扫描中缀表达式 遇到数字加入到后缀表达式 遇到运算符时: 1.若为‘(’,入栈 2.若为’)‘,把栈中的运算符依次加入后缀表达式,直到出现'( ...
- 中缀表达式转后缀表达式(Python实现)
中缀表达式转后缀表达式 中缀表达式转后缀表达式的规则: 1.遇到操作数,直接输出: 2.栈为空时,遇到运算符,入栈: 3.遇到左括号,将其入栈: 4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到 ...
- 栈的简单应用之中缀表达式转后缀表达式(C语言实现逆波兰式)
一.前言 普通人在书写计算式时会选择中缀表达式,这样符合人脑的认知习惯.可计算机处理时后缀表达式才能使处理速度更快,其原因是利用堆栈结构减少计算机内存访问.同时它也是一个很好锻炼栈这个数据结构的应 ...
- 栈的应用实例——中缀表达式转换为后缀表达式
声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...
- 【Weiss】【第03章】练习3.20:中缀表达式转后缀表达式
[练习3.20] a.编写一个程序将中缀表达式转换为后缀表达式,该中缀表达式含括号及四则运算. b.把幂操作符添加到你的指令系统中去. c.编写一个程序将后缀表达式转化为中缀表达式. Answer: ...
随机推荐
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目9
2014-04-23 23:57 题目:如何设计一个内存文件系统,如果可以的话,附上一些代码示例. 解法:很遗憾,对我来说不可以.完全没有相关经验,所以实在无从入手.这题目应该和工作经验相关吧? 代码 ...
- 《Cracking the Coding Interview》——第1章:数组和字符串——题目8
2014-03-18 02:12 题目:判断一个字符串是否由另一个字符串循环移位而成. 解法:首先长度必须相等.然后将第一个串连拼两次,判断第二个串是否在这个连接串中. 代码: // 1.8 Assu ...
- USACO Section2.3 Cow Pedigrees 解题报告 【icedream61】
nocows解题报告------------------------------------------------------------------------------------------ ...
- RPG游戏黑暗之光
1.设置默认鼠标光标 PlayerSettings → Default Cursor 下设置 2.为人物创建单一类 为人物创建了PlayerAnimation.cs.PlayerDir.cs.Play ...
- Ubuntu16.04安装openCV的问题集合
Q1 下列软件包有未满足的依赖关系: libtiff4-dev : 依赖: libjpeg-dev E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系. 上网查了 ...
- 【python基础】--常用数据结构
list tuple dict set四种常用数据结构 list list 有序的集合,可以随时添加.删除其中元素值; 支持list嵌套模式, >>> p = ['a','b']&g ...
- user namespace 2
昨天又试了一下, echo 0 1000 1 > /proc/<PID>/uid_map 想着直接把一个进程的uid设置成root,这样他就可以在自己的user namespace ...
- MVC4.0 bug 神奇的是事情 bool 值变成了 onclick ,非常奇怪的
foreach (var item in ViewBag.PhotoGroupList) { // 这里很奇怪 item.IS_DISPLAY 是布尔值 如果直接写 @item.IS_DISPLAY ...
- android的apk文件结构
什么是APK?APK文件都由那些组成?不懂没关系,让小编来为你详细解答. 一.APK简介与描述 APK是AndroidPackage的缩写,即Android安装包(apk).APK是类似Symbian ...
- Java中的抽象和封装
一.面向对象和面向过程的区别 面向对象: 核心:封装了属性和方法的类,以数据为中心,实现了类级别的代码重用 面向对象因为采用了类,所以具有继承和多态特性,可以进一步重用代码和简化编程 面向过程: 核心 ...