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


目录

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

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

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

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

代码实现过程如下,

完整代码

 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}

接着定义转换函数,

  1. 函数接受一个中缀表达式的可迭代对象,创建列表out存放后缀表达式,以及一个空栈s
  2. 随后开始遍历中缀表达式,判断遍历元素的类型,若为操作数则加入out,
  3. 若为右括号则依次弹出栈内元素加入out列表,直到遇见左括号,弹出左括号不加入out,
  4. 若为普通操作符则压入栈中,并对比栈内操作符优先级,依次弹出高优先级或相同优先级的操作符,
  5. 遍历结束后依次弹出栈内元素,最后返回后缀表达式的字符串形式。
 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 后缀表达式的计算

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

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

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

完整代码

 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] -> 中缀表达式与后缀表达式的转换和计算的更多相关文章

  1. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  2. C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611

    09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...

  3. 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放

    01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...

  4. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  5. 中缀表达式得到后缀表达式(c++、python实现)

    将中缀表达式转换为后缀表达式的算法思想如下: 从左往右开始扫描中缀表达式 遇到数字加入到后缀表达式 遇到运算符时: 1.若为‘(’,入栈 2.若为’)‘,把栈中的运算符依次加入后缀表达式,直到出现'( ...

  6. 中缀表达式转后缀表达式(Python实现)

    中缀表达式转后缀表达式 中缀表达式转后缀表达式的规则: 1.遇到操作数,直接输出: 2.栈为空时,遇到运算符,入栈: 3.遇到左括号,将其入栈: 4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到 ...

  7. 栈的简单应用之中缀表达式转后缀表达式(C语言实现逆波兰式)

    一.前言   普通人在书写计算式时会选择中缀表达式,这样符合人脑的认知习惯.可计算机处理时后缀表达式才能使处理速度更快,其原因是利用堆栈结构减少计算机内存访问.同时它也是一个很好锻炼栈这个数据结构的应 ...

  8. 栈的应用实例——中缀表达式转换为后缀表达式

    声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...

  9. 【Weiss】【第03章】练习3.20:中缀表达式转后缀表达式

    [练习3.20] a.编写一个程序将中缀表达式转换为后缀表达式,该中缀表达式含括号及四则运算. b.把幂操作符添加到你的指令系统中去. c.编写一个程序将后缀表达式转化为中缀表达式. Answer: ...

随机推荐

  1. 自动化测试环境搭建--Python及selenium

    安装pyhton 访问Python官网:http://www.python.org 下载页Windows下找到适合64位系统的版本 下载后双击安装 安装后查看计算机->属性->高级系统设置 ...

  2. win10 ubuntu16双系统安装教程

    一. 知识准备 1.材料 前提: 本文档是在win10 64位下进行安装的!32位的安装注意其中的一些细节即可 硬件: X86_64 位电脑 硬盘有 40G 空闲 软件:[百度搜索即可] (1) Ul ...

  3. 最干净的pyinstaller打包成exe应用程序方法

    在anaconda环境下进行pyinstaller打包后,程序非常大,70行代码打包后有280MB,这是因为会将conda环境携带的库都打包进去导致的.为了获得更纯净的包环境,我们需要安装纯pytho ...

  4. Python保护变量、私有变量、私有方法

    保护变量.私有变量.私有方法介绍: _xxx: 单下划线开头叫保护变量,意思是只有类对象和子类对象自己能访问到这些变量,此变量不能通过from XXX import xxx 导入: __xxx : 双 ...

  5. 解方程 sqrt(x-sqrt(n))+sqrt(y)-sqrt(z)=0的所有自然数解

    解方程 小象同学在初等教育时期遇到了一个复杂的数学题,题目是这样的: 给定自然数 nn,确定关于 x, y, zx,y,z 的不定方程 \displaystyle \sqrt{x - \sqrt{n} ...

  6. 更优雅的清除浮动float方法

    上篇文章是利用 :after 方法清除浮动float(作用于浮动元素的父元素上). ; } //为了兼容性,因为ie6/7不能使用伪类,所以加上此行代码. .outer:after {;;visibi ...

  7. vb如何将数据库中某个字段显示在一个文本框

    Dim mrc As ADODB.Recordset Private Sub cmdQuery_Click() Dim txtSQL As String Dim MsgText As String t ...

  8. hadoop2.6.4【ubuntu】单机环境搭建 系列1

    jdk安装 tar zxvf jdk mv jdk /usr/lib/jvm/java jdk环境变量配置 vim /etc/profile ``` export JAVA_HOME=/usr/lib ...

  9. [hdu6435]Problem J. CSGO

    题目大意:给定$n$个$A$类元素和$m$个$B$类元素,每类元素有值$S$和$k$个值$x_0,x_1,\dots,x_{k-1}(k\leqslant 5)$. 要求选出一个$A$类元素$a$和$ ...

  10. [bzoj3218] a+b problem [最小割+数据结构优化建图]

    题面 传送门 思路 最小割 我们首先忽略掉那个奇♂怪的限制,就有一个比较显然的最小割模型: 建立源点$S$和汇点$T$ 对于每个元素$i$建立一个点$i$,连边$<S,i,w[i]>$和$ ...