數(shù)據(jù)結(jié)構(gòu)-棧

棧(stack)是限制插入和刪除只能在一個(gè)位置上進(jìn)行的表,該位置是表的末端,叫做棧的頂(top)。對(duì)棧的基本操作有Push(進(jìn)棧)和Pop(出棧),前者相當(dāng)于插入,后者則是刪除最后插入的元素。

1. 平衡符號(hào)

編譯器檢查你的程序的語(yǔ)法錯(cuò)誤,但是常常由于少一個(gè)符號(hào)(如遺漏一個(gè)花括號(hào)或是注釋起始符)引起編譯器列出上百行的診斷,而真正的錯(cuò)誤并沒有找出。
在這種情況下一個(gè)有用的程序就是檢驗(yàn)是否每件事情都能成對(duì)出現(xiàn)。于是,每一個(gè)右花括號(hào)、右方括號(hào)及右圓括號(hào)必然對(duì)應(yīng)其相應(yīng)的左括號(hào)。序列[()]是合法的,但[(])是錯(cuò)誤的。
這里可以使用一個(gè)簡(jiǎn)單的棧算法,敘述如下:
做一個(gè)空棧。讀入字符直到文件尾。如果字符是一個(gè)開放符號(hào),則將其推入棧中。如果字符是一個(gè)封閉符號(hào),則當(dāng)??諘r(shí)報(bào)錯(cuò)。否則,將棧元素彈出。如果彈出的符號(hào)不是對(duì)應(yīng)的開放符號(hào),則報(bào)錯(cuò)。在文件尾,如果棧非空則報(bào)錯(cuò)。

2. 函數(shù)調(diào)用

檢測(cè)平衡符號(hào)的算法提供一種實(shí)現(xiàn)函數(shù)調(diào)用的方法。函數(shù)調(diào)用和函數(shù)返回基本上類似于開括號(hào)和閉括號(hào)。只不過多了函數(shù)執(zhí)行位置和局部變量的儲(chǔ)存問題。這里就不進(jìn)行詳細(xì)描述了。

3. 后綴記法(同時(shí)也叫做逆波蘭記法)

正常表達(dá)式:4.99 * 1.06 + 5.99 + 6.99 * 1.06
后綴表達(dá)式:4.99 1.06 * 5.99 + 6.99 1.06 * +

例子:6 5 2 3 + 8 * + 3 + *
首先,將四個(gè)字符放入棧中,此時(shí)棧變成


image.png

下面讀到一個(gè)" + "號(hào),所以3和2從棧中彈出,并且它們的和5被壓入棧中。


image.png

接著,8進(jìn)棧。


image.png

現(xiàn)在見到一個(gè)" * "號(hào),因此8和5彈出,并且5 * 8 = 40 進(jìn)棧。


image.png

接著又見到一個(gè)" + "號(hào),因此40和5被彈出,并且5 + 40 = 45進(jìn)棧。


image.png

現(xiàn)在將3壓入棧中。


image.png

然后" + "使得3和45從棧中彈出,并將45 + 3 = 48壓入棧中。


image.png

最后,遇到一個(gè)" * "號(hào),從棧中彈出48和6,將結(jié)果6 * 48 = 288壓進(jìn)棧中。


image.png

4. 中綴到后綴的轉(zhuǎn)換

原則:

  • 讀到操作數(shù)的時(shí)候,立即把它放到輸出中。操作符則是放入棧中。當(dāng)遇到左圓括號(hào)時(shí)我們也要將其推入棧中。
  • 如果遇到一個(gè)右括號(hào),那么就將棧元素彈出,將彈出的符號(hào)放到輸出中,反復(fù)執(zhí)行,直到我們遇到一個(gè)(對(duì)應(yīng)的)左括號(hào),但是這個(gè)左括號(hào)只被彈出,并不輸出。
  • 如果我們見到任何其他的符號(hào)(+,*,(),那么我們從棧中彈出棧元素直到發(fā)現(xiàn)優(yōu)先級(jí)更低的元素為止
  • 這里有一個(gè)例外:除非是在處理一個(gè))的時(shí)候,否則我們絕不從棧中移走(。對(duì)于這種操作,+的優(yōu)先級(jí)最低,而(的優(yōu)先級(jí)最高。
  • 最后,如果我們讀到了輸入的末尾,我們將棧元素彈出直到該棧變成空棧,將符號(hào)寫到輸出中。
    例子:
    a + b * c + (d * e + f) * g
    轉(zhuǎn)為 a b c * + d e * f + g * +
    首先,a被讀入,于是它流向輸出。然后,+被讀入并被放入棧中。接著是b讀入并流向輸出。
    image.png

這時(shí)*號(hào)讀入。操作符棧的棧頂元素比*的優(yōu)先級(jí)低,故沒有輸出,*進(jìn)棧。接著c被讀入并輸出。

image.png

后面的符號(hào)是一個(gè)+號(hào)。需要將*從棧彈出并放到輸出中;彈出棧中剩下的+號(hào),該符號(hào)不比剛剛遇到的+號(hào)優(yōu)先級(jí)低而是有相同的優(yōu)先級(jí);然后,將剛剛遇到的+號(hào)壓入棧中。

image.png

下一個(gè)被讀到的符號(hào)是一個(gè)(,由于有最高的優(yōu)先級(jí),因此它被放進(jìn)棧中。然后,d讀入并輸出。

image.png

繼續(xù)進(jìn)行,我們又讀到一個(gè)*。除非正在處理閉括號(hào),否則開括號(hào)不會(huì)從棧中彈出,因此沒有輸出。下一個(gè)是e,它被讀入并輸出。

image.png

再往后讀到的符號(hào)是+。我們將*彈出并輸出,然后將+壓入棧中。這以后,我們讀到f并輸出。

image.png

現(xiàn)在,我們讀到一個(gè)),因此將棧元素直到(彈出,我們將一個(gè)+號(hào)輸出。

image.png

下面又讀到一個(gè)*,該符號(hào)被壓入棧中。然后,g被讀入并輸出。

image.png

現(xiàn)在輸入為空,因此我們將棧中的符號(hào)全部彈出并輸出,直到棧變成空棧


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容