逆波兰表达式算法原理记录

原始逆波兰式算法(未考虑负数、函数调用情况)

1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
      (1) 该运算符为左括号"(",则直接存入运算符堆栈。
      (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止,此时抛弃该左括号。
      (3) 该运算符为非括号运算符:
      (a) 若运算符堆栈栈顶的运算符为左括号,则直接存入运算符堆栈。
      (b) 若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。
      (c) 若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,直至运算符栈栈顶运算符低于(不包括等于)该运算符优先级,或为左括号,
           并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。


改进的逆波兰式算法(考虑负数、函数调用情况)

1.构建两个栈Operand(操作数栈)和Operator(操作符栈)和一个LAST_TOKEN标记字段。

2.扫描给定的字符串,扫描时注意跳过空格,提取完整的操作数、操作符和函数。

3.如果获得一个运算符(用B代替)首先构造响应的运算符,构造时需要比较LAST_TOKEN记录字段,来判断重载的操作符的含义,比如如果LAST_TOKEN是数字,那么“-”就是一    个数学运算符,如果LAST_TOKEN是运算符,那么要看“-”后面是不是数字,如果是数字,则认为“-”是“负号”。构造好Operator后和Operator栈栈顶元素(用A替代)比      较:

1)如果A不存在,则把B压入Operator栈中;

2)如果B是一个左括号,则忽略A和B的优先级比较,把B压入Operator栈。

3)如果B是逗号,同样忽略A和B的比较,把B压入Operator栈。

4)如果B是一个右括号,则把Operator栈顺序出栈,然后把弹出的元素顺序压入Operand栈中,出栈是需要判断逗号情况,如果是逗号,则不入栈,记录逗号个数,直到栈顶弹出       的是左括号,括号不入Operand栈中。之后看Operator栈顶元素,如果栈顶元素是函数类型,则把函数Operator出栈然后将逗号个数+1构造数字操作数压入Operand栈中,然       后把函数Operator也压入Operand栈中。

5)如果A是左括号,则把B直接压入Operator栈。

6)如果B优先级比A高,则把B直接压入Operator栈。

7)如果B优先级低于或等于A的优先级,则把A出栈然后压入Operand栈,反复进行此步骤直到栈顶优先级高于B的优先级或者栈顶是一个括号。

4.扫描完毕后,把Operator栈的元素依次出栈,然后依次压入Operand栈中。


时间: 2024-10-29 19:12:03

逆波兰表达式算法原理记录的相关文章

基于逆波兰表达式的公式解析器-算法和思路(一)

背景: 近期项目须要自己完毕Excel的公式解析和求值,在Java中能够使用POI解析Excel公式然后求值.可是项目须要JS端和Java后端均须要支持公式解析,所以就须要自己写一套了.事实上公式解析器整体上并不复杂.原理使用逆波兰表达式就可了. 难点: 1. 针对复杂的用户输入环境解析公式,须要注意公式书写不规范.大写和小写.空格等问题,甚至公式出错的推断. 2. 须要解决函数扩展.函数运行等问题. 3. 须要解决地址.地址范围取数,求值问题. 4. 处理括号带来的优先级提升. 5. 解决公式

【算法】逆波兰表达式

表达式一般由操作数(Operand).运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间, 这称为中缀表达式(Infix Expression),如A+B. 波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式: 把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB: 把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Express

调度场算法与逆波兰表达式

本文的主要内容是如何求一个给定的表达式的值,具体思路就是先将普通算术的中缀表达式转化为后缀表达式,这一步用到的算法叫做调度场算法.然后对后缀表达式,也就是逆波兰表达式求值. 题目:http://acm.hdu.edu.cn/showproblem.php?pid=3596 代码:(参考别人的重构) #include <iostream> #include <string.h> #include <stdio.h> #include <math.h> #inc

北京大学 程序设计与算法(二)逆波兰表达式

用递归解决递归形式的问题 逆波兰表达式 逆波兰表达式是一种把运算符前置的算数表达式,例如普通的表达式2+3的逆波兰表示法为+2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2+3)*3的逆波兰表示法为*+234.本题求解逆波兰表达式的值,其中运算符包括+-*/四个. 输入 输入为一行,其中运算符和运算数之间都用空格分隔,运算符是浮点数 输出 输出为一行,表达式的值. *+11.0 12.0 +24.0 35.0 --à(11.0+12.0)*(24.0+3

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

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出.逆波兰表达式又叫做后缀表达式.这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子: 正常的表达式 逆波兰表达式 a+b ---> a,b,+ a+(b-c) ---> a,b,c,-,+ a+(b-c)d ---> a,d,b,c,-,,+ a=1+3 ---> a=1,3 + http=(smtp+http+telnet)/1024 写成什么呢? http=smtp,http,telnet,+,+,1

波兰、逆波兰表达式

软考习题里遇到了这样一道题,给出了一个逆波兰式,让求它对应的中缀表达式. 逆波兰式:ab-cd+* ,它的中缀表达式是(a-b)*(c+d) 思考: 这让我蒙圈了,这是为什么呢.怎么得到的呢,应该有什么规律的吧. 首先我们要知道: 波兰式:前缀表达式 逆波兰式:后缀表达式 了解这三个表达式之前,我们需要知道 表达式 解释 例子 前缀 不含括号的的算数表达式,将运算符写在前面,操作数写在后面 *+ 2 1 3 中缀 必须含括号,操作符处于操作数的中间 (2+1)*3 后缀 不含括号,运算符放在两个

noi1696 逆波兰表达式

1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制:  1000ms 内存限制:  65536kB 描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4.本题求解逆波兰表达式的值,其中运算符包括+ - * /四个. 输入 输入为一行,其中运算符和运算数之间

逆波兰表达式模型

其实这个东西早在7月开始的时候我就写好了,本来想等小师妹写好了她的版本再放到网上的...无奈她写的实在是太慢了.这个东西还是有改进的空间的,比如升级成浮点模型啥的. 逆波兰表达式的可以以O(N)时间复杂度处理任意表达式,其实也叫后缀表达式,中缀表达式(就是我们一般看到的表达式(1+1=2)),处理的时候分两个栈,一个符号栈,一个表达式栈: (注意我只选二元运算符为例,只处理+-*/和括号) 1. 如果遇到数字,压入表达式栈 2. 如果遇到符号 a. 如果符号是左括号,则直接压入符号栈 b. 如果

Java解析字符串表达式--逆波兰表达式的计算

问题来由: 读入一个字符串形式的四则运算表达式,输出对应的计算结果.如读入的是"6 * ( 5 + ( 2 + 3) * 8 + 3)",那么解析后的输出结果应为288. 思路: 一般的计算过程是这样的,首先计算优先级最高的小括号里面的内容,即"( 5 + ( 2 + 3) * 8 + 3)", 将"2 + 3"的计算结果并存为A,接着用计算"A*8",并存为B 计算"5+B+3",结果存为C 最后计算&q