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

  正常的表达式 逆波兰表达式

  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,+,+,1024,/

  逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)(c+d)转换为ab+cd+

  它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。

计算逆波兰表达式方式如下:

  如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

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

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

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

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

  (4)如果不是数字,该字符则是运算符,此时需比较优先关系。

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

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

  下面是程序化算法流程:

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

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

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

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

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

  若为其它,比较stackOperator栈顶元素与当前元素的优先级:

  如果 栈顶元素 >= 当前元素,出栈并顺序输出运算符直到 栈顶元素 < 当前元素,然后当前元素入栈;

  如果 栈顶元素 < 当前元素,直接入栈。

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

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

  各运算符及符号优先级:

  '\0': -1

  ')': 1

  '(': 2

  '+'、'-': 3

  '*'、'/'、'%': 4

  '^': 5

  其它: 0

/**
* 计算逆波兰表达式的值
*/
function calculate(RPolishArray){
var result = 0;
var tempArray = new Array(100);
var tempNum = -1;
for(i = 0;i < RPolishArray.length;i++){
if(RPolishArray[i].match(/\d/)){
tempNum++;
tempArray[tempNum] = RPolishArray[i];
}else{
switch(RPolishArray[i]){
case '+':
result = (tempArray[tempNum-1] *1) + (tempArray[tempNum] * 1);
tempNum--;
tempArray[tempNum] = result;
break;
case '-':
result = (tempArray[tempNum-1] *1) - (tempArray[tempNum] * 1);
tempNum--;
tempArray[tempNum] = result;
break;
case '*':
result = (tempArray[tempNum-1] *1) * (tempArray[tempNum] * 1);
tempNum--;
tempArray[tempNum] = result;
break;
case '/':
result = (tempArray[tempNum-1] *1) / (tempArray[tempNum] * 1);
tempNum--;
tempArray[tempNum] = result;
break;
}
}
}
result = tempArray[tempNum];
return result;
} /**
* 把普通算术表达式转换为逆波兰表达式
*/
function toRPolish(input){
var regex = /(\(|\)|\+|\-|\*|\/)+/;
var array = input.split(regex);
var RPolish = ""
var isI = false;
num = 0;
var SymbolArray = new Array(100);
var SymbolNum = -1;
for(j = 0;j < input.length;j++){
if(input.charAt(j).match(/\d/)){
if(isI == false){
RPolish += ','
RPolish += array[num];
num++;
isI = true;
}
}
else{
if(SymbolNum == -1){
SymbolNum++;
SymbolArray[SymbolNum] = input.charAt(j);
}else{
if(input.charAt(j).match(/\(/) || SymbolArray[SymbolNum].match(/\(/)){
SymbolNum++;
SymbolArray[SymbolNum] = input.charAt(j);
}else if(input.charAt(j).match(/\)/)){
while(!SymbolArray[SymbolNum].match(/\(/)){
RPolish += ',';
RPolish += SymbolArray[SymbolNum];
SymbolNum--;
}
SymbolNum--;
}else if(compare(input.charAt(j),SymbolArray[SymbolNum])){
SymbolNum++;
SymbolArray[SymbolNum] = input.charAt(j);
}else if(!compare(input.charAt(j),SymbolArray[SymbolNum])){
RPolish += ',';
RPolish += SymbolArray[SymbolNum];
SymbolNum--;
if(SymbolNum >= 0){
if(SymbolArray[SymbolNum].match(/\(/)){
SymbolNum++;
SymbolArray[SymbolNum] = input.charAt(j);
}else if(!compare(input.charAt(j),SymbolArray[SymbolNum])){
RPolish += ',';
RPolish += SymbolArray[SymbolNum];
SymbolArray[SymbolNum] = input.charAt(j);
}else{
SymbolNum++;
SymbolArray[SymbolNum] = input.charAt(j);
}
}else{
SymbolNum++;
SymbolArray[SymbolNum] = input.charAt(j);
}
}
}
isI = false;
}
}
while(SymbolNum >=0){
RPolish += ',';
RPolish += SymbolArray[SymbolNum];
SymbolNum--;
}
regex = /,/;
var RPolishArray = RPolish.split(regex);
return RPolishArray;
} function compare(a,b){
if((a.match(/\*/)||a.match(/\//))&&(b.match(/\+/)||b.match(/\-/))){
return true;
}else{
return false;
}
}

JavaScript实现计算后缀表达式(逆波兰表达式)以及将中缀表达式转为后缀表达式的更多相关文章

  1. java 中缀转后缀(逆波兰)

    import java.util.Stack; public class LeetCode_middleTransformToReversePolish { /** * @param args */ ...

  2. 逆波兰表达式[栈 C 语言 实现]

    逆波兰表达式 逆波兰表达式又叫做后缀表达式.在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示.波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示 ...

  3. C++基础算法学习——逆波兰表达式问题

    例题:逆波兰表达式逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 ...

  4. 关于逆波兰式的c++实现

    正常的表达式 逆波兰表达式 a+b ---> a,b,+ a+(b-c) ---> a,b,c,-,+ a+(b-c)*d ---> a,b,c,-,d,*,+ a+d*(b-c)- ...

  5. C++ | 栈的应用(逆波兰算法) | 计算器

    #include <iostream> using std::cin; using std::cout; using std::endl; template<typename T&g ...

  6. javascript:逆波兰式表示法计算表达式结果

    逆波兰式表示法,是由栈做基础的表达式,举个例子: 5 1 2 + 4 * + 3 -  等价于   5 + ((1 + 2) * 4) - 3 原理:依次将5 1 2 压入栈中, 这时遇到了运算符 + ...

  7. LeetCode_p150_逆波兰表达式计算/后缀表达式计算

    有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说,表达式总会得出有效数值且不存在除 ...

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

    定义: 中缀表达式: 在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表达式 后缀表达式: 又叫逆波兰表达式 ,不包含括号,运算符放在两个运算对象的后面,所有的计算 ...

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

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

随机推荐

  1. 基于 HTML5 + WebGL 的3D无人机 展示

    前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,也被称为“会飞的照相机”.但作为军事使用,无人机的各项性能要求更加严格.重要.本系统则是通过 Hightopo 的   ...

  2. 关于java php go 中AES加解密秘钥长度问题

    今天心血来朝,想用go把php中的一个小功能重写一下,但在解密aes加密的数据时碰到了个坑! php的mcrypt拓展(貌似php7.1版本以上不支持了)提供了aes的加解密: 而且php aes 的 ...

  3. js六种数据类型

    六种数据类型: undefined . boolean  .string .number .object .function 效果地址:https://scrimba.com/c/cEedDGTd 代 ...

  4. ES6的Object.assign()基本用法

    Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). 例如: const target = {a:1}, const source1 ...

  5. Tarjan强连通分量模板

    最好还是看一看下面这个网址吧 我的这篇博客里的代码更加缜密(毫无错误的神级代码)https://www.cnblogs.com/Tidoblogs/p/11315153.html https://ww ...

  6. Elasticsearch系列---实战零停机重建索引

    前言 我们使用Elasticsearch索引文档时,最理想的情况是文档JSON结构是确定的,数据源源不断地灌进来即可,但实际情况中,没人能够阻拦需求的变更,在项目的某个版本,可能会对原有的文档结构造成 ...

  7. 【原创】Dubbo 2.7.5在线程模型上的优化

    这是why技术的第30篇原创文章 这可能是全网第一篇解析Dubbo 2.7.5里程碑版本中的改进点之一:客户端线程模型优化的文章. 先劝退:文本共计8190字,54张图.阅读之前需要对Dubbo相关知 ...

  8. stormzhangB站直播之总结

    此文转自个人微信公众号,原链接为:https://mp.weixin.qq.com/s?__biz=MzUxODk0ODQ3Ng==&mid=2247484313&idx=1& ...

  9. 用户输入- Unity3D游戏开发培训

    用户输入- Unity3D游戏开发培训   作者:Jesai 时间:2018-02-12 14:28:45 用户输入Input 鼠标按键: -方法:GetMouseButton(); -方法:GetM ...

  10. Activiti 手工任务(manualTask)

    Activiti 手工任务(manualTask) 作者:Jesai 前言: 手工任务就是一个自动执行的过程.手动任务几乎不在程序中做什么事情,只是在流程的历史中留下一点痕迹,表明流程是走过某些节点的 ...