javascript使用棧結(jié)構(gòu)將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式并計(jì)算值
1.概念
你可能聽說過表達(dá)式,a+b,a+b*c這些,但是前綴表達(dá)式,前綴記法,中綴表達(dá)式,波蘭式,后綴表達(dá)式,后綴記法,逆波蘭式這些都是也是表達(dá)式。
a+b,a+b*c這些看上去比較正常的是中綴表達(dá)式,就是運(yùn)算符放在兩個(gè)操作數(shù)之間。前綴表達(dá)式是將運(yùn)算符放在相關(guān)操作數(shù)之前,后綴表達(dá)式是將運(yùn)算符放在操作數(shù)之后。
至于前面說的那些概念:
前綴表達(dá)式就是波蘭式就是前綴記法
后綴表達(dá)式就是逆波蘭式就是后綴記法
舉例如下:
(3+4)*5-6就是中綴表達(dá)式
-*+3456就是前綴表達(dá)式
34+5*6-就是后綴表達(dá)式
雖然人的大腦很容易理解與分析中綴表達(dá)式,但是對(duì)于計(jì)算機(jī)來說中綴表達(dá)式確是很復(fù)雜的,因此計(jì)算表達(dá)式的值時(shí)通常需要把中置表達(dá)式轉(zhuǎn)換為前置或者后置表達(dá)式,然后再進(jìn)行求值。對(duì)于計(jì)算機(jī)來說,計(jì)算前綴表達(dá)式或者后置表達(dá)式非常簡(jiǎn)單。
2.中置表達(dá)式轉(zhuǎn)換為后置表達(dá)式
中綴表達(dá)式a + b * c + ( d * e + f ) * g,轉(zhuǎn)化為后綴表達(dá)式之后是a b c * + d e * f + g * +,具體的轉(zhuǎn)換過程如下:
1)如果遇到操作數(shù),直接將其輸出
2)如果遇到操作符,則將其放入棧中,遇到左括號(hào)也將其放入棧中
3)如果遇到一個(gè)右括號(hào),則將棧元素彈出,將彈出的操作符輸出直到遇到左括號(hào)為止,左括號(hào)只彈出不輸出
4)遇到其他的操作符例如 + ,* , (從棧中彈出元素直到遇到發(fā)現(xiàn)更低優(yōu)先級(jí)的元素或者棧空為止。彈出這些元素之后,才能將遇到的操作符壓入到棧中,有一點(diǎn)要注意,只有遇到 ) 的情況下才彈出 ( 其他情況下都不會(huì)彈出 (
5)如果讀到了輸入的末尾,則將棧中的所有元素依次彈出
3.示例
規(guī)則很多,還是用實(shí)例比較容易說清楚整個(gè)過程。以上面的轉(zhuǎn)換為例,輸入為a + b * c + (d * e + f)*g,處理過程如下:
1)首先讀到a,直接輸出。
2)讀到“+”,將其放入到棧中。
3)讀到b,直接輸出。
表達(dá)式 * c + (d * e + f) * g, 此時(shí)棧和輸出的情況如下:
4)讀到“*”,因?yàn)闂m斣?+"優(yōu)先級(jí)比" * " 低,所以將" * "直接壓入棧中。
5)讀到c,直接輸出。
表達(dá)式 + (d * e + f) * g, 此時(shí)棧和輸出情況如下:
6)讀到" + ",因?yàn)闂m斣? * "的優(yōu)先級(jí)比它高,所以彈出" * "并輸出, 同理,棧中下一個(gè)元素" + "優(yōu)先級(jí)與讀到的操作符" + "一樣,所以也要彈出并輸出。然后再將讀到的" + "壓入棧中。
表達(dá)式 (d * e + f) * g,此時(shí)棧和輸出情況如下:
7)下一個(gè)讀到的為"(",它優(yōu)先級(jí)最高,所以直接放入到棧中。
8)讀到d,將其直接輸出。
表達(dá)式 * e + f) * g,此時(shí)棧和輸出情況如下:
9)讀到" * ",由于只有遇到" ) "的時(shí)候左括號(hào)"("才會(huì)彈出,所以" * "直接壓入棧中。
10)讀到e,直接輸出。
表達(dá)式 + f) * g,此時(shí)棧和輸出情況如下:
11)讀到" + ",彈出" * "并輸出,然后將"+"壓入棧中。
12)讀到f,直接輸出。
表達(dá)式 ) * g,此時(shí)棧和輸出情況:
13)接下來讀到“)”,則直接將棧中元素彈出并輸出直到遇到"("為止。這里右括號(hào)前只有一個(gè)操作符"+"被彈出并輸出。
表達(dá)式 * g
14)讀到" * ",壓入棧中。讀到g,直接輸出。
表達(dá)式為空
15)此時(shí)輸入數(shù)據(jù)已經(jīng)讀到末尾,棧中還有兩個(gè)操作符“*”和" + ",直接彈出并輸出。表達(dá)式 a + b * c + (d * e + f) * g

至此整個(gè)轉(zhuǎn)換過程完成。程序?qū)崿F(xiàn)代碼后續(xù)再補(bǔ)充了
4.后綴表達(dá)式求值
假設(shè)一個(gè)后綴表達(dá)式為 6 5 2 3 + 8 * + 3 + * ,則其求值過程如下:
1)遍歷表達(dá)式,遇到的數(shù)字首先放入棧中,此時(shí)棧如下所示:
2)接著讀到“+”,則彈出3和2,執(zhí)行3+2,計(jì)算結(jié)果等于5,并將5壓入到棧中。
3)讀到8,將其直接放入棧中。
4)讀到“*”,彈出8和5,執(zhí)行8*5,并將結(jié)果40壓入棧中。而后過程類似,讀到“+”,將40和5彈出,將40+5的結(jié)果45壓入棧...以此類推。最后求的值288。
//使用數(shù)組dataStore保存站內(nèi)元素,構(gòu)造函數(shù)將其初始化為一個(gè)空數(shù)組。 //變量top定義棧頂?shù)奈恢茫瑯?gòu)造時(shí)初始化為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的當(dāng)前位置對(duì)應(yīng)的位置,同時(shí)top自加1,指向下一個(gè)位置 function push(element){ this.dataStore[this.top++] = element; } //返回棧頂元素,同時(shí)top的位置減1 function pop(){ return this.dataStore[--this.top]; } //peek()方法返回?cái)?shù)組的第top-1個(gè)位置的元素,即棧頂元素 function peek(){ return this.dataStore[this.top-1]; } //將top的值設(shè)置0,即清空一個(gè)棧 function clear(){ this.top = 0; } //返回變量top的值即為棧內(nèi)元素的個(gè)數(shù) function length(){ return this.top; } //輸出棧內(nèi)元素 function printStack(){ while (this.top>0){ document.writeln(this.pop()+" "); } } } /*-------------------棧將中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式-------------------*/ 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(); /*-------------------用棧結(jié)構(gòu)求后綴表達(dá)式的值-------------------*/ 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();
輸出結(jié)果如下:

作者:Tyler Ning
出處:http://www.rzrgm.cn/tylerdonet/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,如有問題,請(qǐng)微信聯(lián)系冬天里的一把火
浙公網(wǎng)安備 33010602011771號(hào)