python中缀表达式转后缀表达式,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与数据结构&lbrack;1&rsqb; -&gt&semi; 栈&sol;Stack&lbrack;0&rsqb; -&gt&semi; 链表栈与数组栈的 Python 实现

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

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

#!/usr/bin/env python # -*- coding: utf-8 -*- # learn <

中缀表达式得到后缀表达式&lpar;c&plus;&plus;、python实现&rpar;

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

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

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

栈的简单应用之中缀表达式转后缀表达式&lpar;C语言实现逆波兰式&rpar;

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

栈的应用实例&mdash&semi;&mdash&semi;中缀表达式转换为后缀表达式

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

【Weiss】【第03章】练习3&period;20:中缀表达式转后缀表达式

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

RPN-逆波兰计算器-中缀表达式转后缀表达式-javascript

1.利用栈(Stack)来存储操作数和操作符: 2.包含中缀表达式转后缀表达式的函数,这个是难点,也是关键点: 2.1.将输入字符串转为数组: 2.2.对转换来的字符进行遍历:创建一个数组,用来给存储 ...

随机推荐

Leetcode Median of Two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

GridView合并表头、多重表头(转)

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { switch (e.Row.RowType) ...

(转载)PHP 提示和技巧

(转载)http://www.111cn.net/phper/21/b4aea31507014a778b18682943db402f.htm 1. 当您在寻找关于某个具体的 PHP 函数的信息时,请转 ...

linux c 系统报错

本文中的错误是指在代码编译完全正确程序可运行的情况下,因为没有成功调用程序中的某些系统调用函数而产生的错误.往往这些系统调用函数通过返回值(比如1,0,-1)来说明其是否调用成功,而程序员需要知道详细 ...

eclipse&period;ini内存设置

这两天用eclipse,突然变得很卡,就上网找了些资料,对eclipse.ini启动参数配置,整理如下: 1.先了解下JVM内存管理机制,JVM内存分为堆内存和非堆内存 2.JVM内存限制 首先JVM ...

最新Node&period;js 资源汇总

Node.js 资源汇总 文档 Node.js 官方文档:http://nodejs.org/api/ Node.js 中文文档:http://nodejs.jsbin.cn/api/ Express ...

Debugging java application with netbean

Debugging Java Applications with NetBeans    from:https://manikandanmv.wordpress.com/2009/09/24/debu ...

在html后面拼接字符串后页面的跳转

我就举一个简单的栗子,主要目的是实现页面跳转时后面获取的参数

点击我可以跳转
样式就随便写一下 之后 ...

线程间操作无效&colon; 从不是创建控件&OpenCurlyDoubleQuote;button1”的线程访问它。

.net2后是不能跨线程访问控件的.,窗体上的控件是当前线程创建的,当用户异步执行一个方法:在该方法中给窗体上的控件赋值,记住:当执行一个异步委托的时候,其实 就是开了一个线程去执行那个方法,这样就会 ...

测试开发之Django——No1&period;介绍以及引申

前言 > 测试行业发展飞速,自动化测试兴起,由此对测试人员的要求与日俱增.随时而来的,就是职能的增加. > 首先需要学习的,就是自动化测试.而由自动化测试引申而来的,就是另外几个新增的岗位 ...

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值