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: ...
随机推荐
- jpg、png、gif图片格式的浅析
原文地址:图片格式与设计那点事儿 之前面试时被面试官问到了jpg.gif.png格式的区别,当时就扯了一些,感觉都是扯淡,上网搜了下,分享一篇文章 第一次写技术博客,有不尽如人意的地方,还请见谅和指正 ...
- android surfaceview 入门介绍
由于工作中需自定义控件,以前没写过. 开始时,实用view 实现了,经理说不好,担心效率低,要求每秒需要刷新10次左右. 然后,学习使用 surfaceview. 看了网上简单的Demo,找到him ...
- (原)App源码
序) 人生就像卫生纸,有事没事少扯 前言) 最近偶尔和一位极客大牛聊了一次,这个极客在汇编的造诣算是相当高,不过野路子出来看不起各种规矩,因此是适合做个自己蒙头研究技术的极客男,不适合大型团队,不适合 ...
- Python列表深浅复制详解
转自:https://www.cnblogs.com/blaomao/p/7239203.html 在文章<Python 数据类型>里边介绍了列表的用法,其中列表有个 copy() 方法, ...
- 小程序使用Canvas画饼图
先上效果图 -------------------------------------------------------------wxml代码开始------------------------- ...
- Appium与python自动测试环境及demo详解
App--UI自动化这种高端的名词已经被越来越多的人所高呼,可是从实际角度来讲,个人觉得还是有点鸡肋,不如接口自动化敏捷度高,工作量 也是接口自动化的好几倍.但是,[划重点了] 在技术时代中,作为测 ...
- python3编写脚本之--------购物车
我这里的购物车的大概内容是: 1.首先要知道商品的有什么东西可卖,需要多少钱. 2.买家准备花多少钱去购物商品,购买的商品先放在购物车里. 3.最后买家还可以是否确定购买购物车的东西,还剩多 ...
- java的四种内部类(转)
一般来说,有4中内部类:常规内部类.静态内部类.局部内部类.匿名内部类. 一.常规内部类:常规内部类没有用static修饰且定义在在外部类类体中. 1.常规内部类中的方法可以直接使用外部类的实例变量 ...
- BZOJ 2458: [BeiJing2011]最小三角形 | 平面分治
题目: 给出若干个点 求三个点构成的周长最小的三角形的周长(我们认为共线的三点也算三角形) 题解: 可以参考平面最近点对的做法 只不过合并的时候改成枚举三个点更新周长最小值,其他的和最近点对大同小异 ...
- BZOJ 1043 【bzoj1043】[HAOI2008]下落的圆盘 | 暴力么??
题目: 题解: 大概是黄学长的博客 #include<cstdio> #include<algorithm> #include<cstring> #include& ...