当前课程知识点:数据结构(上) > 第四章 栈与队列 > (c5)栈应用:逆波兰表达式 > 04C5-3 手工
我们先来学习所谓的手工转换法
为此 我们或许需要假定
自己是从别的星球来的外星人
也就是说 根本就不知道地球人
是怎么约定中缀表达式中
不同运算符的优先级关系的
但是有一条 我们知道括号是很有用的
通过括号 即使我是来自于外星的
也可以明确的定义 在每一个表达式中
每一个运算符的先后运算关系
虽然这样会显得有点罗嗦
没错
我们确实刚开始的时候
需要把这个事情弄复杂
正像有一句名言所说的那样
如欲取之 必先予之
虽然我们接下来 要尽可能地去增加括号
但是我们最终的目的
却是希望将所有的括号都予以消除
就以这个表达式为例
首先我们需要显式的
添加一系列必要的括号
使得确实每一个运算符的运算次序
都可以毫无含糊地被来自于
任何一个星球的人所理解
为了校核方便
我们这里使用了圆括号
方括号和大括号
此时的每一对括号
实际上都唯一的对应于某一个操作符
比如这一对括号所帮助界定的
就是阶乘运算的优先级
而这对括号呢 所界定的
应该就是乘法运算的优先级
而再往外的这一对括号
所界定的当然也就是加法运算
如果你还愿意再继续举例
我们可以看到这对圆括号
实际上帮助界定的
就是这个减号的运算次序
接下来 我们要将每一个运算符
后移到适当的位置上去
什么位置呢?
也就是帮助界定它的那对括号中的
右括号的紧邻右侧
所以 这个减号将会被移到
它所对应的那个右括号的右侧
这个加号也将会被后移到
它所对应的那个右括号的紧邻右侧
这个乘号也是如此
阶乘号也是如此
请大家特别留意这一点
比如说 在这个例子中
我们就发现有这么样一个现象
在如此将运算符分别后移之后
它们未必保持此前的相对次序
这也很好理解
因为正如刚才我们所说的
在RPN中
这些运算符将按照它们
自左向右的次序来真正执行
而在原表达式中
显然 并不是所有的运算符
都有这样左先右后的次序
好
如果说这一步是予之的话
那么我们就可以取之了
也就是说 我们可以将
所有的括号都统统抹去
它们的历史使命已经完成
留下来的将是原来的那样一组操作数
以及重新调整位置之后的操作符
它们合并起来
就是原来那个中缀表达式
所对应的逆波兰表达式
这里有一个非常重要的特征
我们刚才讲过
经过这样的转换之后
运算符之间的相对次序是有可能颠倒
至少是改变的
但是运算数的相对次序
是绝对不会改变的
因为从刚才这个转换的过程
我们可以看得到
它们根本就没有动过窝
原来待在什么位置
依然待在什么位置
即便是在经过重新整理之后
它们的相对次序也是不变的
现在你应该明白了
邓老师在举这些例子的时候
为什么总是爱举0 1 2 3 一直到9了吧?
没错
这是在帮助你理解
并且记忆这样一个重要的规律
我再强调一遍
所有的操作数 在RPN中的相对次序
与它们在中缀表达式中的次序
总是保持一致的
不会变化
在这样的例子中
原先是单调的
此后依然是单调的
反之亦然
那么 这样一个手工转换的过程
如何具体地实现为一个算法呢?
其实这个问题你不应该来问我
我们早就学过了
难道不是吗?
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)计算
--演示
--(a)计算--作业
-(b)计算模型
-(b)计算模型--作业
-(c)大O记号
-(c)大O记号--作业
-(d)算法分析
-(d)算法分析--作业
-(e)迭代与递归
-(e)迭代与递归--作业
-(xc)动态规划
-- 演示
-(xc)动态规划--作业
-本章测验--作业
-(a)接口与实现
--02A-5 复制
-(a)接口与实现--作业
-(b)可扩充向量
-(b)可扩充向量--作业
-(c)无序向量
--02C-1 概述
--02C-3 插入
--02C-6 查找
--02C-8 遍历
-(c)无序向量--作业
-(d1)有序向量:唯一化
-(d1)有序向量:唯一化--作业
-(d2)有序向量:二分查找
-(d2)有序向量:二分查找--作业
-(d3)有序向量:Fibonacci查找
-(d3)有序向量:Fibonacci查找--作业
-(d4)有序向量:二分查找(改进)
-(d4)有序向量:二分查找(改进)--作业
-(d5)有序向量:插值查找
-第二章 向量(下)--(d5)有序向量:插值查找
-(e)起泡排序
--02E-2 改进
--02E-3 反例
-(e)起泡排序--作业
-(f)归并排序
-(f)归并排序--作业
-本章测验--作业
-(a)接口与实现
--03A-4 实现
-(a)接口与实现--作业
-(b)无序列表
--03B-2 查找
-(b)无序列表--作业
-(c)有序列表
--03C-3 查找
-(c)有序列表--作业
-(d)选择排序
--03D-1 构思
--03D-2 实例
--03D-3 实现
--03D-4 推敲
--03D-6 性能
-(d)选择排序--作业
-(e)插入排序
--03E-1 经验
--03E-2 构思
--03E-3 对比
--03E-4 实例
--03E-5 实现
-(e)插入排序--作业
-(xd)习题辅导:LightHouse
-本章测验--作业
- (a)栈接口与实现
--04A-1 栈
--04A-2 实例
--04A-3 实现
- (a)栈接口与实现--作业
-(c1)栈应用:进制转换
-第四章 栈与队列--(c1)栈应用:进制转换
-(c2)栈应用:括号匹配
-(c2)栈应用:括号匹配--作业
-(c3)栈应用:栈混洗
-第四章 栈与队列--(c3)栈应用:栈混洗
-(c4)栈应用:中缀表达式求值
-(c4)栈应用:中缀表达式求值--作业
-(c5)栈应用:逆波兰表达式
-第四章 栈与队列--(c5)栈应用:逆波兰表达式
-(d)队列接口与实现
--04D-1 接口
--04D-2 实例
--04D-3 实现
-第四章 栈与队列--本章测验
-(a)树
--05A-1 动机
--05A-2 应用
-(a)树--作业
-(b)树的表示
--05B-2 父亲
--05B-3 孩子
-第五章 二叉树--(b)树的表示
-(c)二叉树
-(c)二叉树--作业
-(d)二叉树实现
-(d)二叉树实现--作业
-(e1)先序遍历
-(e1)先序遍历--作业
-(e2)中序遍历
-第五章 二叉树--(e2)中序遍历
-(e4)层次遍历
-第五章 二叉树--(e4)层次遍历
-(e5)重构
-(e5)重构--作业
-本章测验--作业
-(a)概述
-(a)概述--作业
-(b1)邻接矩阵
-(b1)邻接矩阵--作业
-(c)广度优先搜索
--06C-2 策略
--06C-3 实现
--06C-5 实例
-(c)广度优先搜索--作业
-(d)深度优先搜索
--06D-1 算法
--06D-2 框架
--06D-3 细节
-(d)深度优先搜索--作业
-第六章 图--本章测验