1. 程式人生 > >數據結構 棧解析 算法表達式

數據結構 棧解析 算法表達式

個數 一個 分析 () amp 掃描表 ble 遇到 lpad

1 本文目標

分析用堆棧解析算術表達式的基本方法。給出的示例代碼能解析任何包括+,-,*,/,()和0到9數字組成的算術表達式。

2 中綴表達式和後綴表達式

中綴表達式就是通常所說的算術表達式,比如(1+2)*3-4。

後綴表達式是指通過解析後,運算符在運算數之後的表達式,比如上式解析成後綴表達式就是12+3*4-。這種表達式可以直接利用棧來求解。

3 運算符的優先級

優先級 運算符
1 括號()
2 負號-
3 乘方**
4 乘*,除/,求余%
5 加+,減-
6 小於<,小於等於<=,大於>,大於等於>=
7 等於==,不等於!=
8 邏輯與&&
9 邏輯或||


大致的規律是,一元運算符 > 二元運算符 > 多元運算符。

4 利用堆棧解析算術表達式的過程

中綴表達式翻譯成後綴表達式的方法如下:

(1)從右向左依次取得數據ch。

(2)如果ch是操作數,直接輸出。

(3)如果ch是運算符(含左右括號),則:
a:如果ch = ‘(‘,放入堆棧。
b:如果ch = ‘)‘,依次輸出堆棧中的運算符,直到遇到‘(‘為止。
c:如果ch不是‘)‘或者‘(‘,那麽就和堆棧頂點位置的運算符top做優先級比較。
1:如果ch優先級比top高,那麽將ch放入堆棧。
2:如果ch優先級低於或者等於top,那麽輸出top,然後將ch放入堆棧。

(4)如果表達式已經讀取完成,而堆棧中還有運算符時,依次由頂端輸出。

如果我們有表達式(A-B)*C+D-E/F,要翻譯成後綴表達式,並且把後綴表達式存儲在一個名叫output的字符串中,可以用下面的步驟。

(1)讀取‘(‘,壓入堆棧,output為空
(2)讀取A,是運算數,直接輸出到output字符串,output = A
(3)讀取‘-‘,此時棧裏面只有一個‘(‘,因此將‘-‘壓入棧,output = A
(4)讀取B,是運算數,直接輸出到output字符串,output = AB
(5)讀取‘)‘,這時候依次輸出棧裏面的運算符‘-‘,然後就是‘(‘,直接彈出,output = AB-
(6)讀取‘*‘,是運算符,由於此時棧為空,因此直接壓入棧,output = AB-
(7)讀取C,是運算數,直接輸出到output字符串,output = AB-C
(8)讀取‘+‘,是運算符,它的優先級比‘*‘低,那麽彈出‘*‘,壓入‘+",output = AB-C*
(9)讀取D,是運算數,直接輸出到output字符串,output = AB-C*D
(10)讀取‘-‘,是運算符,和‘+‘的優先級一樣,因此彈出‘+‘,然後壓入‘-‘,output = AB-C*D+
(11)讀取E,是運算數,直接輸出到output字符串,output = AB-C*D+E
(12)讀取‘/‘,是運算符,比‘-‘的優先級高,因此壓入棧,output = AB-C*D+E
(13)讀取F,是運算數,直接輸出到output字符串,output = AB-C*D+EF
(14)原始字符串已經讀取完畢,將棧裏面剩余的運算符依次彈出,output = AB-C*D+EF/-

5 計算算術表達式


當有了後綴表達式以後,運算表達式的值就非常容易了。可以按照下面的流程來計算。

(1)從左向右掃描表達式,一個取出一個數據data
(2)如果data是操作數,就壓入堆棧
(3)如果data是操作符,就從堆棧中彈出此操作符需要用到的數據的個數,進行運算,然後把結果壓入堆棧
(4)如果數據處理完畢,堆棧中最後剩余的數據就是最終結果。

比如我們要處理一個後綴表達式1234+*+65/-,那麽具體的步驟如下。

(1)首先1,2,3,4都是操作數,將它們都壓入堆棧
(2)取得‘+‘,為運算符,彈出數據3,4,得到結果7,然後將7壓入堆棧
(3)取得‘*‘,為運算符,彈出數據7,2,得到數據14,然後將14壓入堆棧
(4)取得‘+‘,為運算符,彈出數據14,1,得到結果15,然後將15壓入堆棧
(5)6,5都是數據,都壓入堆棧
(6)取得‘/‘,為運算符,彈出數據6,5,得到結果1.2,然後將1.2壓入堆棧
(7)取得‘-‘,為運算符,彈出數據15,1.2,得到數據13.8,這就是最後的運算結果

數據結構 棧解析 算法表達式