当前课程知识点:数据结构(上) > 第四章 栈与队列 > (c5)栈应用:逆波兰表达式 > 04C5-4 算法
回到我们此前所学过的
中缀表达式的求值算法
相信你已经对这个算法比较熟悉了
所以我们这里为了简便
只列出了其中最主要的框架
这个算法在对中缀表达式
进行求值的同时
也捎带着完成了RPN的转换和生成
你现在应该知道
为什么这个接口
需要提供一个名为RPN的
引用型的字符串了吗?
对了
它最终返回的就是原来
中缀表达式所对应的RPN
如果你对这个还有点怀疑的话
建议你打开我们的示例代码
并且对这段代码进行编译执行
如果你的方法得当
我相信你应该能看到
RPN转化的详细过程
以及最终的结果
如果我们对这个算法
进行一个关键词RPN的搜索
我们会发现 对RPN的引用和修改
无非只出现在两个位置
第一处位置对应的是
我们当前扫到的这个字符
是一个数字digit
我们曾经讲过
这意味着遇到了一个数字
因此我们可以通过
readNumber把这个数字读进来
那么它将作为一个操作数
被推入操作数栈中
而随即呢?大家看到
我们可以非常简明地
直接将刚刚推入栈顶的这个操作数
续接到当前的RPN尾部
而else另一种情况
也就是当前的字符实际上
是一个运算符的时候
我们并没有急于像刚才运算数那样
直接把它后缀到RPN的尾部
而是只在某些特定的时候
才将它缀在其后
什么时候呢?
我们可以看到
在else这个分支底下
还有很多个sub case子分支
其中只有当对应于
大于号的优先级关系
也就是说
栈顶的这个元素可以立即执行的时候
当然 只要表达式的语法正确
每一个运算符都会入栈
而且都会等到它应该执行的那一天
那这一天是什么时候呢?
考察任意的这样一个运算符
以及它所对应的那个子表达式
还有无论是显式的
还是像刚才我们手动方法
那样加入的隐式的
总会有一对对应的括号
我们说只有当我们的求值算法
扫描到这个显式的
或者隐式的括号的时候
这个运算符执行的时机
也恰好就在此时
请注意
对应的那个右括号 就是
这个运算符被真正执行的时机
所以反过来 我们就在它
真正执行的那个时候
将它续接到RPN的尾部
其实完全就等同于
我们刚才在手动的算法中
将这个运算符移到紧邻于
它所对应的这个右括号的右侧
二者实际上在做同一件事情
只不过刚才你需要纸和笔
而现在呢 是由这个算法
聪明地简便地帮你实现的
好了
现在你应该对这样一个
原本是用来求值的算法
同时还能够正确地完成RPN转换
不存质疑了吧?
在说再见之前
我还希望大家和我一起
来反观一下这段程序
我们可以看到 对于操作数来说
每遇到一个就随即接至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)深度优先搜索--作业
-第六章 图--本章测验