中缀表达式变后缀表达式、后缀表达式(逆波兰)求值(python版本)

时间:2022-10-22 08:52:49

定义:

中缀表达式: 在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表达式

后缀表达式: 又叫逆波兰表达式 ,不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *

一个字符串表达式s = “9 + ( 3 - 1 ) * 3 + 10 / 2”)求值的过程分为两步

(一) 将 中缀表达式s变为后缀表达式s_after = "9 3 1 - 3 * + 10 2 / +",具体的规则如下 :

首先维护两个空栈,(stack_exp)存放逆波兰表达式,(stack_ops)暂存操作符,运算结束后stack_ops必为空

循环遍历字符串(将表达式分为四种元素 1、数值; 2、操作符; 3、 左括号; 4、右括号),具体情况如下

1、遇到数值, 将该值入栈stack_exp

2、遇到左括号, 将左括号入栈stack_ops

3、遇到右括号,将stack_ops中的操作符从栈顶依次出栈并入栈stack_exp, 直到第一次遇到左括号终止操作(注意: 该左括号出栈stack_ops但不入栈stack_exp)至此消除表达式中的一对括号

4、遇到四则运算操作符号(+ - * /)

4-1、 如果stack_ops为空, 操作符入栈stack_ops

4-2、 如果stack_ops不空,将stack_ops栈顶操作符与遍历到的操作符(op)比较:

4-2-1: 如果stack_ops栈顶操作符为左括或者op优先级高于栈顶操作符优先级, op入栈stack_ops,当前遍历结束

4-2-2: 如果op优先级小于或者等于stack_ops栈顶操作符, stack_ops栈顶操作符出栈并入栈stack_exp,重复4-1、 4-2直到op入栈stack_ops

5、字符串遍历结束后如果stack_ops栈不为空,则依次将操作符出栈并入栈stack_exp

python代码实现如下:

ops_rule = {
'+': 1,
'-': 1,
'*': 2,
'/': 2
} def middle_to_after(s):
expression = []
ops = []
ss = s.split(' ')
for item in ss:
if item in ['+', '-', '*', '/']:
while len(ops) >= 0:
if len(ops) == 0:
ops.append(item)
break
op = ops.pop()
if op == '(' or ops_rule[item] > ops_rule[op]:
ops.append(op)
ops.append(item)
break
else:
expression.append(op)
elif item == '(':
ops.append(item)
elif item == ')':
while len(ops) > 0:
op = ops.pop()
if op == '(':
break
else:
expression.append(op)
else:
expression.append(item) while len(ops) > 0:
expression.append(ops.pop()) return expression
(二) 将后缀表达式s_after = "9 3 1 - 3 * + 10 2 / +" 求值,具体的规则如下 :
初始化一个空栈stack_value,用于存放数值
循环s_after
1、 如果遇到数字,入栈stack_value;
2、 如果遇到运算符, 从stack_value中依次出栈两个数(先出栈的在右, 后出栈的在左)连同遍历到的运算符组成二目运算,求值后将结果压栈stack_value
3、 继续遍历下一个元素,直到结束
遍历完后stack_value中的结果便是表达式的值
python代码实现如下:
def expression_to_value(expression):
stack_value = []
for item in expression:
if item in ['+', '-', '*', '/']:
n2 = stack_value.pop()
n1 = stack_value.pop()
result = cal(n1, n2, item)
stack_value.append(result)
else:
stack_value.append(int(item))
return stack_value[0] def cal(n1, n2, op):
if op == '+':
return n1 + n2
if op == '-':
return n1 - n2
if op == '*':
return n1 * n2
if op == '/':
return n1 / n2 if __name__ == '__main__':
expression = middle_to_after('9 + ( 3 * ( 4 - 2 ) ) * 3 + 10 / 2')
value = expression_to_value(expression)
print value

  

 
 


中缀表达式变后缀表达式、后缀表达式(逆波兰)求值(python版本)的更多相关文章

  1. JavaScript实现计算后缀表达式(逆波兰表达式)以及将中缀表达式转为后缀表达式

    逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出.逆波兰表达式又叫做后缀表达式.这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子: 正常的表达式 逆波兰表达式 a+b ...

  2. 刁肥宅详解中缀表达式求值问题:C++实现顺序/链栈解决

    1. 表达式的种类 如何将表达式翻译成能够正确求值的指令序列,是语言处理程序要解决的基本问题,作为栈的应用事例,下面介绍表达式的求值过程. 任何一个表达式都是由操作数(亦称运算对象).操作符(亦称运算 ...

  3. [LeetCode] 150. Evaluate Reverse Polish Notation 计算逆波兰表达式

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  4. LeetCode 150:逆波兰表达式求值 Evaluate Reverse Polish Notation

    题目: 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. Evaluate the value of an arithm ...

  5. C++之字符串表达式求值

    关于字符串表达式求值,应该是程序猿们机试或者面试时候常见问题之一,昨天参加国内某IT的机试,压轴便为此题,今天抽空对其进行了研究. 算术表达式中最常见的表示法形式有 中缀.前缀和 后缀表示法.中缀表示 ...

  6. NYOJ--257--郁闷的C小加(一)(中缀表达式变后缀表达式 )

    郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...

  7. 中缀表达式转逆波兰式(后缀表达式)求值 C++ Stack

    给一个包含小数的中缀表达式 求出它的值 首先转换为后缀表达式然后利用stack求出值 转换规则: 如果字符为'('  push else if 字符为 ')' 出栈运算符直到遇到‘(' else if ...

  8. C++ 中缀转后缀表达式并求值

    //中缀转后缀 #include<iostream> #include<stack> using namespace std; int prio(char x){ ; ; ; ...

  9. leetcode算法学习----逆波兰表达式求值(后缀表达式)

    下面题目是LeetCode算法:逆波兰表达式求值(java实现) 逆波兰表达式即后缀表达式. 题目:  有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式.同 ...

随机推荐

  1. 准确理解SO&lowbar;REUSEADDR

          默认情况下,套接字不同一个正在使用的本地地址绑定到一起.但在少数情况下,仍有必要以这种方式,来实现对一个地址的重复利用.每个连接都是通过它的本地及远程地址的组合,"独一无二&qu ...

  2. nginx重定向规则入门

    nginx重定向规则的入门实例 时间:2015-12-17 15:18:03来源:网络 导读:nginx重定向规则,Nginx的重定向模块HttpRewriteModule的用法说明,nginx重定向 ...

  3. CAF(C&plus;&plus; actor framework)使用随笔(send sync&lowbar;send)(二)

    a). 发完就忘, 就像上面anon_send 以及send #include <iostream> #include "caf/all.hpp" #include & ...

  4. 超详细SDK Hello World

    Windows应用程序的基本运行机制与HelloWin程序详细解 总的来说最基本的Windows应用程序的运行执行顺序总是以如下的基本顺序执行的. 顺序结构: 调用WinMain函数开始执行--à定义 ...

  5. 走进React

    走进React React是一个构建用户界面的JavaScript库,是Facebook公司在2013年5月在github上开源的.其特点如下: 高效--React通过对DOM的模拟,最大程度地减少和 ...

  6. java面向对象(五)之多态

    多态 面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. ...

  7. J&period;U&period;C FutureTask之源码解析

    通过直接继承Thread, 实现Runnable接口来创建线程.但这两种方式都有一种缺陷:在执行完任务之后无法获得执行结果. 如果需要获得执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果, ...

  8. nagios的安装

    Nagios通常由一个主程序(Nagios).一个插件程序(Nagios-plugins)和四个可选的ADDON(NRPE.NSCA. NSClient++和NDOUtils)组成.Nagios的监控 ...

  9. FPGA學習筆記(貳)--- 流水燈

    平臺:FPGA黑金开发板 AX301 開發環境:Quartus Prime Version 17.0.0 Build 595 04/25/2017 Standard Edition 引脚配置:鼠標托拉 ...

  10. array中key所对应的value

    获取数组中的键对应的值 class Test{ public function index(){ $info = array( 'name' => 'daicr', 'age' => 24 ...