Python逆波兰表达式
1.先创建SqStack类,用于操作顺序栈
class SqStack:# 构造函数def __init__(self):self.data = [] # 声明空列表,作为栈的存放元素# 判断栈是否为空def empty(self):if len(self.data) == 0:return Truereturn False# 进栈def push(self, item):self.data.append(item)# 出栈def pop(self):assert not self.empty() # 判断栈是否为为空return self.data.pop() # pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。# 取栈顶元素def get_top(self):assert not self.empty()return self.data[-1] # data[-1]取出倒数第一个数
2.创建ExpressClass类,用于获取中缀表达式转后缀表达式(逆波兰表达式),以及获取后缀表达式的值
- 创建init构造函数
- 创建get_post_exp函数,获取后缀表达式
- 创建trans函数,中缀表达式转后缀表达式
- 创建get_value,获取后缀表达式的值
from SqStack import SqStackclass ExpressClass:def __init__(self, str):self.exp = str # 中缀表达式存放位置self.post_exp = [] # 后缀表达式存放位置def get_post_exp(self): # 返回后缀表达式return self.post_expdef trans(self): # 中缀转后缀opor = SqStack() # 创建空栈i = 0 # 栈下标while i < len(self.exp):ch = self.exp[i] # 取出栈元素if ch == "(": # 遇到左括号,入符号栈opor.push(ch)elif ch == ")": # 遇到右括号,需要取出符号栈元素,追加到后缀表达式栈中while not opor.empty() and opor.get_top() != "(":e = opor.pop() # 将"("之前的所有元素退栈,因为在栈中"("之前的意思是在"("后进去的元素,出来的时候在"("之前出self.post_exp.append(e) # 把符号追加到后缀栈中opor.pop() # 將“(”退栈elif ch == "+" or ch == "-": # 入符号栈# 先取出符号栈的栈顶元素,判断是否是(,如果不是,则把符号栈的符号取出来入后缀表达式栈while not opor.empty() and opor.get_top() != "(":e = opor.pop()self.post_exp.append(e)# 如果符号栈是(,则直接入栈opor.push(ch)elif ch == "*" or ch == "/": # 入符号栈while not opor.empty():e = opor.get_top() # 获取栈顶元素if e != "(" and (e == "*" or e == "/"):e = opor.pop()self.post_exp.append(e)else:breakopor.push(ch) # 把符号入栈else: # 就是数字,入后缀表达式栈d = "" # 保存数字# 判断是否是数字while "0" <= ch <= "9": # 判断是否为数字,如果是,则一直取出所有数字d += chi += 1if i < len(self.exp): # 如果当前项为最后一项,因为先加1,则会超出索引,所以要先判断,超出最后一项,则结束所有循环,也就是breakch = self.exp[i] # 取出当前下标的元素else:break # 退出所有循环i -= 1 # 循环完毕则退格,减1只适合最大2位数的数字运算self.post_exp.append(int(d)) # 后缀表达式入i += 1# 判断符号栈是否为空,没空,就把元素压入后缀栈中while not opor.empty():self.post_exp.append(opor.pop())# 获取后缀表达式的值def get_value(self):opand = SqStack() # 创建空栈 # 创建空栈i = 0 # 栈的下标while i < len(self.post_exp):opv = self.post_exp[i] # 从头0取出栈中的元素if opv == "+": # 如果遇到+a, b = opand.pop(), opand.pop()c = a + bopand.push(c) # 计算结果再放入栈elif opv == "-":a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,减数后入,出栈时减数先出,所以a是减数c = b - aopand.push(c) # 计算结果再放入栈elif opv == "*":a, b = opand.pop(), opand.pop()c = a * bopand.push(c) # 计算结果再放入栈elif opv == "/":a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,分母后入,出栈时分母先出,所以a是分母assert a != 0 # 分母不为0c = b / aopand.push(c) # 计算结果再放入栈else:opand.push(opv) # 如果不是符号,则直接入栈opandi += 1return opand.get_top() # 返回栈顶元素
3.最后创建main类
from ExpressClass import ExpressClassif __name__ == '__main__':ex = ExpressClass("(56-20)/(4+2)")ex.trans()print(ex.get_post_exp())print(ex.get_value())
我们测试一下(56-20)/(4+2), 得如下图
扩展:无栈类实现
原理都是一样的,只是把栈类换成列表
# 未使用SqStack类
def get_value(str):opand = [] # 创建空栈 # 创建空栈i = 0 # 栈的下标while i < len(str):opv = str[i] # 从头0取出栈中的元素if opv == "+": # 如果遇到+a, b = opand.pop(), opand.pop()c = int(a) + int(b)opand.append(c) # 计算结果再放入栈elif opv == "-":a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,减数后入,出栈时减数先出,所以a是减数c = int(b) - int(a)opand.append(c) # 计算结果再放入栈elif opv == "*":a, b = opand.pop(), opand.pop()c = int(a) * int(b)opand.append(c) # 计算结果再放入栈elif opv == "/":a, b = opand.pop(), opand.pop() # 此处先获取a,再获取b,入栈时,分母后入,出栈时分母先出,所以a是分母assert a != 0 # 分母不为0c = int(b) / int(a)opand.append(c) # 计算结果再放入栈else:opand.append(opv) # 如果不是符号,则直接入栈opandi += 1return opand[-1] # 返回栈顶元素if __name__ == '__main__':ipt = input()ipt = list(ipt.split())re = get_value(ipt)print(re)
测试案例:[56, 20, '-', 4, 2, '+', '/']
Python逆波兰表达式相关推荐
- python杂记-逆波兰表达式求解
逆波兰表达式求解一般是基于堆栈的,求解过程是:操作数入栈,遇到操作符时,操作数出栈,求值,将结果入栈:运行一遍后,栈顶就是表达式的值.因此逆波兰表达式的求值使用堆栈结构很容易实现,并且能很快求值. 比 ...
- 数据结构链表之栈——解决括号匹配问题和逆波兰表达式求值问题——6
括号匹配问题和逆波兰表达式求值问题 基于上一节已经使用python代码对栈进行了简单的实现,这一节我们在其基础上解决两个常见的问题 案例 括号匹配问题(点我直接到代码实现) 逆波兰表达式求值问题(点我 ...
- 逆波兰表达式-----------红黑树--------mysql(DDL)----生产者消费者模式
逆波兰表达式 二元运算符的表达式定义为:(操作数) + (运算符) + (操作数) ,其中操作数也可以为表达式. 在计算机中,根据运算符所在的不同位置来命名,表达式可以有如下三种不同的表示方法: 记表 ...
- (补)算法训练Day13 | LeetCode150. 逆波兰表达式求值(栈应用);LeetCode239. 滑动窗口最大值(单调队列);LeetCode347. 前K个高频元素(小顶堆,优先级队列)
目录 LeetCode150. 逆波兰表达式求值 1. 思路 2. 代码实现 3. 复杂度分析 4. 思考 LeetCode239. 滑动窗口最大值 1. 思路 2. 代码实现 3. 复杂度分析 4. ...
- LeetCode实战:逆波兰表达式求值
题目英文 Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are ...
- 【Java】LeetCode 150. 逆波兰表达式求值 (后缀表达式)
题目: 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话 ...
- 数据结构:后缀表达式(逆波兰表达式)
逆波兰表达式计算 package com.atchina.stack;import java.util.ArrayList; import java.util.List; import java.ut ...
- 数据结构:前缀,中缀,后缀表达式(逆波兰表达式)
前缀表达式(波兰表达式) 前缀表达式的运算符位于操作数之前. 比如 (1+2)*3-4 对应的前缀表达式就是: - * + 1 2 3 4 前缀表达式的计算机求值 从右至左扫描表达式,遇到数字时,就 ...
- LetCode: 150. 逆波兰表达式求值
提示 LintCode中的相关算法题实现代码,可以在我的GithHub中下载. 题目需求 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另 ...
- Algorithm:C++语言实现之链表相关算法(单链公共结点问题、一般LCA、括号匹配、最长括号匹配、逆波兰表达式Reverse Polish Notation、直方图矩形面积、收集雨水问题)
Algorithm:C++语言实现之链表相关算法(单链公共结点问题.一般LCA.括号匹配.最长括号匹配.逆波兰表达式Reverse Polish Notation.直方图矩形面积.收集雨水问题) 目录 ...
最新文章
- 计算机上机报告-origin,Origin 8上机练习1
- perl判断CGI程序或终端程序的方法
- 教你在Python中构建物体检测系统(附代码、学习资料)
- Oracle 10g 用户数及价格
- 抖音直播APP软件系统为什么能这么火?反映出的问题又会是什么?
- vue父子组件间传参
- 集中火力,专项击破!数据分析可视化广深线下培训火热来袭
- 数据库操作之——约束
- slam十四讲第十讲:找不到 g2o_viewer
- 【优化算法】变色龙算法(CSA)【含Matlab源码 1796期】
- 惠普win7驱动_hp打印机驱动如何安装 hp打印机驱动安装方法【步骤详解】
- sourceTree中git工作流使用
- matlab altera视频,Altera 官网中文视频教程 下载地址
- 学习日记day25 平面设计 综合例子
- 《中医确有专长证》和《中医专长医师资格证》的区别
- Elasticsearch配置拼音分词和自定义分词器
- swiper的基础使用(十五)
- python延迟实现
- GhostNets on Heterogeneous Devices via Cheap Operations
- 《程序员的自我修养》读书总结