算法题:逆波兰表达式(数学逆波兰表达式和交并集逆波兰表达式)

一、前言

在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,所以,这种表示 法也称为中缀表示。每一运算符都置于其运算对象之后,称为后缀表达式,后缀表达式又叫做逆波兰表达式。 它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:如果当前 字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表 达式扫描完后,栈里的就是结果。

二、一般算法

将一个普通的中序表达式转换为逆波兰表达式 的一般算法是:

(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级 最低的特殊符号“#”。

(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字 ,则分析到该数字串的结束并将该数字串直接输出。

(4)如果不是数字,该字符则是运算符,此时需比 较优先关系。做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运 算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优 先级低于当前运算符,将该字符入栈。

(5)重复上述操作(3)-(4)直至扫描完整个简单算术表达式,确 定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式 。

三、算法流程

程序化算法流程:

1、建立运算符栈stackOperator用于运算符的存储,压入'\'。

2、预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号) 为正负号) 。

3、顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接输出该数字; 如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。

4、若当前运算符为' (',直接入栈;

若为')',出栈并顺序输出运算符直到遇到第一个'(',遇到的 第一个'('出栈但不输出;

若为四则运算符,比较栈顶元素与当前元素的优先级:    如果栈顶元素运算符优先级 >= 当前元素的优先级,出栈并顺序输出运算符直到 栈顶元素优先级 < 当前元素优先级,然后当前元素入栈;如果栈顶元素 < 当前元素,直接入栈。

5、重复第3点 直到表达式扫描完毕。

6、顺序出栈并输出运算符直到栈顶元素为'\0'。

四、相关类图

本文主要包括RpnExpression基类、MathExpression以及 IntersectionUnionExpresion。

MathExpression主要用于计算简单数学运算(+、-、*和/)。

IntersectionUnionExpresion主要用于计算交并集运算(|、&)。

懒得用UML来画图,直 接用VS2012生成的类图,如下所示:

时间: 2024-09-19 10:12:09

算法题:逆波兰表达式(数学逆波兰表达式和交并集逆波兰表达式)的相关文章

算法题:poj 2541 Binary Witch(KMP水过,逆序转换)

链接: http://poj.org/problem?id=2541 分析与总结: 做这题估算了下复杂度,觉得无论KMP再怎么快,这题暴力也肯定要超时的. 想了很久也没想出个好办法,于是决定暴力之,但是TLE了....于是就放了几天.之后看了下discuss ,这题的正解应该是状态压缩dp,不过目前我还不懂,跪了. 之后百度发现也可以用KMP水过,虽然是因为数据水才过的,不过这种思路很巧妙,值得借鉴! 直接暴力是枚举字符串的后面13个的字母,然后再用KMP匹配,这样的话,就绪要枚举多次,分别是

算法题——投篮比赛获胜概率问题

问题描述: 甲乙两人比赛投篮.约定甲先投篮,每人投篮投进一球,则继续投球,若投失一球,则换人投球.初始积分为1分,甲每投进一球,积分加1分:乙每投进1球,积分减1分.若积分达到N分(N>1),甲获胜:若积分减至0分,乙获胜.假定甲投进的概率为P1(0<P1<1),乙投进的概率为P2(0<P2<1).那么这场投篮比赛,甲获胜的概率P为多少?     很显然的,甲获胜的概率P是和P1.P2.N相关的. P1越大,P越大 P2越大,P越小 N越大,P越小   不失一般性,假设P1=

经典算法题每日演练——第三题 猴子吃桃

原文:经典算法题每日演练--第三题 猴子吃桃           猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾就多吃了一个.第二天早上又将剩下的桃子吃了一半,还是不过瘾又多 吃了一个.以后每天都吃前一天剩下的一半再加一个.到第10天刚好剩一个.问猴子第一天摘了多少个桃子?   分析: 这是一套非常经典的算法题,这个题目体现了算法思想中的递推思想,递归有两种形式,顺推和逆推,针对递推,只要         我们找到递推公式,问题就迎刃而解了.                令S10=1,容易看

一个算法题,求答案啊啊啊啊

问题描述 一个算法题,求答案啊啊啊啊 白班 09:00-18:00 通班 09:00-21:00 每个人每个月通班数量必须等于早中班和中晚班数量之和 早中班 09:00-15:00 中晚班 15:00-21:00 假设:每月按照30计算. 排班规则: 1.每个人每个月固定休息6天连续上班天数不超过7天. 2.每天各班次上班的人数最低需求:8个白班5个通班1个早中班,2个中晚班. 3.每个月每个人的通班天数安排不超过8天. 4.每个人每个月早中班和中晚班的天数之和需要与通班天数相等. 5.每月最多

算法题:把阿拉伯金额转化为汉字表示的金额

n年没写算法题了,今天用了20分钟写了一个,要求如题,感觉算法有所退步,老了 using System; using System.Text; namespace money { class Program { static void Main(string[] args) { StringBuilder sb=new StringBuilder(); var strValue = Console.ReadLine(); var strlist = strValue.Split('.'); if

算法题:HDU 2594 Simpsons’ Hidden Talents(KMP)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2594 题目大意: 给两个字符串s1和s2, 求出是s1的前缀并且是s2的后缀的最长的字符串. 分析与总结: 真正理解好KMP算法,这题就是水题. 首先求出s1的失配函数,然后在s2中 寻找s1字符串. 在寻找字符串过程中,会有一个状态值j,这个值表示的是当前在s2中已经匹配 了多少个s1的字符. 所以,全部匹配完后,最后j的值就是以s2的最后一个字符结尾,和s1的前缀相匹 配的最长字符串.也就是所求的

算法题:uva 10318

题目链接: 首先,可以确定每个格子只能选一次,因为选任何大于0的偶数次,等于没有效果 一样. 然后,就可以把这题理解成从r*c的矩阵中选择一些格子进行"点亮"操作,使得最终所 有格子都是"亮"的状态.那么,每个格子要么有点亮操作,要么没有,总共复杂度为2^25,显然必须 进行减枝. 假设从第一行第一列开始,从左往右,从上往下一次依次选择,对于当前所在位置( x, y),它已经不能影响到x-2以前的行数了,所以当到x行时,如果第x-2行没有全部点亮,则进行减枝 . 此

算法题:uva 1330

题目链接: http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&category=460&page=show_problem&problem=4076 以前做过一道一维的,这题只是变成了二维的,其他方法都一样.HDU 1506  Largest Rectangle in a Histogram   题解 代码1: #include<cstdio> #include<cs

求一个面试算法题答案。

问题描述 求一个面试算法题答案. 已知函数f()以相同的概率返回0或者1,求一个函数g()以相同的概率返回0-7之间的任意一个数字. 解决方案 其实这个题不难,可以考虑用2进制的方式来做.g(){return 4*f()+2*f()+f();} 希望能帮到你. 解决方案二: #includeint g(){srand(time(NULL));ret = rand()%8;return ret;}