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: ...
随机推荐
- DataGridView重查后,返回原来所在行
首先记录选中行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //查询前记录选中行 int _currentRow = 0; //int _cu ...
- Pascal数据结构与算法
第一章 数据结构与算法的引入 1.1 数据结构的基本概念 一. 学习数据结构的意义 程序设计 = 数据结构 + 算法 目前,80%的待处理的数据具有“算法简单”(四则运算.检索.排序等),“对象复杂” ...
- PL/SQL 循环语句
1.基本 LOOP 循环语句 语法: LOOP 语句序列; END LOOP; 其中,语句序列中需要一个EXIT语句或一个EXIT WHEN语句来中断循环. 实例: DECLARE x ) :; BE ...
- 在python中如何比较两个float类型的数据是否相等
奇怪的现象 前几天跟同事聊起来,在计算机内部float比较是很坑爹的事情.比方说,0.1+0.2得到的结果竟然不是0.3? >>> 0.1+0.2 0.300000000000000 ...
- JDK从1.8升级到9.0.1后sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用
目录 描述 原因分析 处理办法 参考 描述 最近研究把项目的JDK升级从1.8升级到9.0.1,在eclipse上配置好JDK为9后,发现项目有错,查看发现sun.misc.BASE64Decoder ...
- 移动平台自动化测试:appium(一)
Appium 是一个开源的,跨平台的自动化测试工具.它支持模拟器(iOS,FirefoxOS,Android)和真机(iOS, Android, FirefoxOS)上的原生应用,混合应用和移动 we ...
- 【bzoj2424】[HAOI2010]订货 费用流
原文地址:http://www.cnblogs.com/GXZlegend/p/6825296.html 题目描述 某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di, ...
- 【Luogu】P2489迷宫探险(概率DP)
题目链接 设f[i][j][k][l]是当前在(i,j),对陷阱的了解状态为k(0表示了解该陷阱为无危险,1表示了解该陷阱有危险,2不了解),l表示当前血,走出迷宫的概率 dfsDP即可. 注意随时更 ...
- java中的UDP总结
先说一下关于InetAddress类,用一个小例子: import java.net.InetAddress; import java.net.UnknownHostException; public ...
- Avito Cool Challenge 2018:C. Colorful Bricks
C. Colorful Bricks 题目链接:https://codeforces.com/contest/1081/problem/C 题意: 有n个横向方块,一共有m种颜色,然后有k个方块的颜色 ...