1.概念

  你可能听说过表达式,a+b,a+b*c这些,但是前缀表达式,前缀记法,中缀表达式,波兰式,后缀表达式,后缀记法,逆波兰式这些都是也是表达式。

  a+b,a+b*c这些看上去比较正常的是中缀表达式,就是运算符放在两个操作数之间。前缀表达式是将运算符放在相关操作数之前,后缀表达式是将运算符放在操作数之后。

  至于前面说的那些概念:

  前缀表达式就是波兰式就是前缀记法

  后缀表达式就是逆波兰式就是后缀记法

举例如下:

(3+4)*5-6就是中缀表达式

-*+3456就是前缀表达式

34+5*6-就是后缀表达式

  虽然人的大脑很容易理解与分析中缀表达式,但是对于计算机来说中缀表达式确是很复杂的,因此计算表达式的值时通常需要把中置表达式转换为前置或者后置表达式,然后再进行求值。对于计算机来说,计算前缀表达式或者后置表达式非常简单。

2.中置表达式转换为后置表达式

中缀表达式a + b * c + ( d * e + f ) * g,转化为后缀表达式之后是a b c * + d e * f  + g * +,具体的转换过程如下:

1)如果遇到操作数,直接将其输出

2)如果遇到操作符,则将其放入栈中,遇到左括号也将其放入栈中

3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止,左括号只弹出不输出

4)遇到其他的操作符例如 + ,* , (从栈中弹出元素直到遇到发现更低优先级的元素或者栈空为止。弹出这些元素之后,才能将遇到的操作符压入到栈中,有一点要注意,只有遇到 ) 的情况下才弹出 ( 其他情况下都不会弹出 (

5)如果读到了输入的末尾,则将栈中的所有元素依次弹出

3.示例

规则很多,还是用实例比较容易说清楚整个过程。以上面的转换为例,输入为a + b * c + (d * e + f)*g,处理过程如下:

1)首先读到a,直接输出。

2)读到“+”,将其放入到栈中。

3)读到b,直接输出。

表达式  * c + (d * e + f) * g, 此时栈和输出的情况如下:

4)读到“*”,因为栈顶元素"+"优先级比" * " 低,所以将" * "直接压入栈中。

5)读到c,直接输出。

表达式  + (d * e + f) * g, 此时栈和输出情况如下:

6)读到" + ",因为栈顶元素" * "的优先级比它高,所以弹出" * "并输出, 同理,栈中下一个元素" + "优先级与读到的操作符" + "一样,所以也要弹出并输出。然后再将读到的" + "压入栈中。

表达式 (d * e + f) * g,此时栈和输出情况如下:

7)下一个读到的为"(",它优先级最高,所以直接放入到栈中。

8)读到d,将其直接输出。

表达式  * e + f) * g,此时栈和输出情况如下:

9)读到" * ",由于只有遇到" ) "的时候左括号"("才会弹出,所以" * "直接压入栈中。

10)读到e,直接输出。

表达式  + f) * g,此时栈和输出情况如下:

11)读到" + ",弹出" * "并输出,然后将"+"压入栈中。

12)读到f,直接输出。

表达式 ) * g,此时栈和输出情况:

13)接下来读到“)”,则直接将栈中元素弹出并输出直到遇到"("为止。这里右括号前只有一个操作符"+"被弹出并输出。

表达式  * g

14)读到" * ",压入栈中。读到g,直接输出。

表达式为空

15)此时输入数据已经读到末尾,栈中还有两个操作符“*”和" + ",直接弹出并输出。表达式 a + b * c + (d * e + f) * g

至此整个转换过程完成。程序实现代码后续再补充了

4.后缀表达式求值

假设一个后缀表达式为 6 5 2 3 + 8 * + 3 + * ,则其求值过程如下:

1)遍历表达式,遇到的数字首先放入栈中,此时栈如下所示:

2)接着读到“+”,则弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。

3)读到8,将其直接放入栈中。

4)读到“*”,弹出8和5,执行8*5,并将结果40压入栈中。而后过程类似,读到“+”,将40和5弹出,将40+5的结果45压入栈...以此类推。最后求的值288。

//使用数组dataStore保存站内元素,构造函数将其初始化为一个空数组。
//变量top定义栈顶的位置,构造时初始化为0,表示栈的起始位置为0
function Stack(){
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
this.clear = clear;
this.length = length;
this.printElement = printStack; //注意++操作符的位置,它放在this.top的后面,这样新入栈的元素就被放在top的当前位置对应的位置,同时top自加1,指向下一个位置
function push(element){
this.dataStore[this.top++] = element;
}
//返回栈顶元素,同时top的位置减1
function pop(){
return this.dataStore[--this.top];
}
//peek()方法返回数组的第top-1个位置的元素,即栈顶元素
function peek(){
return this.dataStore[this.top-1];
}
//将top的值设置0,即清空一个栈
function clear(){
this.top = 0;
}
//返回变量top的值即为栈内元素的个数
function length(){
return this.top;
} //输出栈内元素
function printStack(){
while (this.top>0){
document.writeln(this.pop()+"  ");
}
}
} /*-------------------栈将中缀表达式转换成后缀表达式-------------------*/
document.write('<br><br>');
function suffixExpression(){
var str = 'a+b*c+(d*e+f)*g';
var stack = new Stack();
var outStack = new Array();
for (var i=0; i<str.length; ++i) {
if(')' == str[i]){
while (true){
var top = stack.peek();
stack.pop();
if('(' != top){
outStack[outStack.length] = top;
}else{
break;
}
}
}else if(['-','+'].indexOf(str[i])>-1){
if(['*','/'].indexOf(stack.peek())>-1){
while (['*','/'].indexOf(stack.peek())>-1){
outStack[outStack.length] = stack.peek();
stack.pop();
}
outStack[outStack.length] = str[i];
}else{
stack.push(str[i]);
}
}else if(['(','*','/'].indexOf(str[i])>-1){
stack.push(str[i]);
}else{
outStack[outStack.length] = str[i];
}
} for (var i=0; i< outStack.length; i++) {
document.write(outStack[i]);
} }
suffixExpression();
/*-------------------用栈结构求后缀表达式的值-------------------*/
document.write('<br><br>');
function countSuffixExpression(){
var str = '6523+8*+3+*';
var stack = new Stack();
for (var i=0; i<str.length; i++) {
if(isNaN(str[i])){
stack.push( eval( stack.pop() + str[i] + stack.pop()) );
}else{
stack.push(str[i])
}
} document.write(stack.pop());
}
countSuffixExpression();

输出结果如下:

javascript使用栈结构将中缀表达式转换为后缀表达式并计算值的更多相关文章

  1. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  2. 栈的应用实例——中缀表达式转换为后缀表达式

    声明:本程序读入一个中缀表达式,将该中缀表达式转换为后缀表达式并输出后缀表达式. 注意:支持+.-.*./.(),并且输入时每输入完一个数字或符号都要加一个空格,特别注意的是在整个表达式输入完成时也要 ...

  3. 练习3.20 a 将中缀表达式转换为后缀表达式

    //将中缀表达式转换为后缀表达式 int main() { ; ]={,,,,,,,}; char tmp; PtrToStack s; s = CreateStack( MaxSize ); ) { ...

  4. 数据结构Java实现06----中缀表达式转换为后缀表达式

    本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后 ...

  5. 中缀表达式转换为后缀表达式(python实现)

    中缀表示式转换为后缀表达式 需要一个存放操作符的栈op_stack,输出结果的列表output 步骤: 从左到右遍历表达式: 1. 若是数字,直接加入到output 2. 若是操作符,比较该操作符和o ...

  6. Infix to postfix conversion 中缀表达式转换为后缀表达式

    Conversion Algorithm 1.操作符栈压入"#": 2.依次读入表达式的每个单词: 3.如果是操作数则压入操作数栈: 4.如果是操作符,则将操作符栈顶元素与要读入的 ...

  7. Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算

    中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操 ...

  8. 中缀表达式得到后缀表达式(c++、python实现)

    将中缀表达式转换为后缀表达式的算法思想如下: 从左往右开始扫描中缀表达式 遇到数字加入到后缀表达式 遇到运算符时: 1.若为‘(’,入栈 2.若为’)‘,把栈中的运算符依次加入后缀表达式,直到出现'( ...

  9. 中缀表达式转后缀表达式(Java代码实现)

    后缀表达式求值 后缀表达式又叫逆波兰表达式,其求值过程可以用到栈来辅助存储.例如要求值的后缀表达式为:1 2 3 + 4 * + 5 -,则求值过程如下: 遍历表达式,遇到数字时直接入栈,栈结构如下 ...

随机推荐

  1. 自己写方法处理WP(RT)后退键事件处理

    不用微软的NavigationHelper,自己写方法处理WP后退键事件 在WP8.1(RT)程序中,你会发现按下后退键时,应用会直接退出,变为后台运行,这是因为RT与Silverlight对后退键的 ...

  2. sap透明表、结构、簇介绍以及查找表方法

    sap透明表.结构.簇介绍以及查找表方法 一些人在写开发功能说明书的时候不知道如何去找屏幕字段对应的透明表,下面我来介绍一个比较有效的方法:首先简单介绍一下概念:在SAP中的表的种类有以下三种:Tra ...

  3. 详解HTML5中rel属性的prefetch预加载功能使用

    在HTML5中,有个很有用但常被忽略的特性,就是预先加载(prefetch),它的原理是: 利用浏览器的空闲时间去先下载用户指定需要的内容,然后缓存起来,这样用户下次加载时,就直接从缓存中取出来,效率 ...

  4. 桥牌笔记:Show up Squeeze显露挤牌法

    南主打4S,注意一个叫牌过程,西家叫过加倍,东家应叫过2D. 西连打红桃K.A,然后再打红桃J让东家将吃.东家上手后,回小方块.此时庄家已经失了3墩了,如何完成这个4S? 庄家必须拿到所有剩下的牌墩. ...

  5. bash shell命令(1)

    本文地址:http://www.cnblogs.com/archimedes/p/bash-shell1.html,转载请注明源地址. ls命令 ls用来列出目录的内容,它是用户最常用的命令之一,ls ...

  6. Python基础(6)--条件、循环

    本文的主要内容是 Python 的条件和循环语句以及与它们相关的部分. 我们会深入探讨if, while, for以及与他们相搭配的else,elif,break,continue和pass语句. 本 ...

  7. 使用VideoView自定义一个播放器控件

    介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了.在写VideoView播放视频时候定义控制的代码全写在Actv ...

  8. MYSQL性能调优: 对聚簇索引和非聚簇索引的认识

    聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法.特点是存储数据的顺序和索引顺序一致.一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引. 在<数据库原理&g ...

  9. 在MFC中添加用户自定义消息

    1.定义一个宏 (用户自定义消息从WM_USER开始) #define WM_XXXXX WM_USER+数值 2.声明一个函数并实现 afx_msg LRESULT OnXXXXX( WPARAM ...

  10. sass+compass+bootstrap三剑合璧高效开发记录

    1. 先搭建环境,下载node.js,rubyinstaller,安装, 安装rubyinstaller时,要选上include system path,这样就会自动将node.js执行添加到wind ...