3 32+ 5 3* -
12 34 2- * 8 /
乍一看上面兩個式子很奇怪,是嗎?它們就是這裡所要講到的一種運算式的記法——逆波蘭運算式。
現在,準備一個很窄的圓筒,筒是有底的,像一個細長的杯子,粗細剛好和一枚硬幣相當。再做幾個和硬幣一樣大的小圓紙片,在紙片上依次寫上“3”“32”“+”“5”“3”“*”“-”,記住,每個紙片上要麼唯寫一個數,要麼唯寫一個運算子號,把它們按上面的順序排好。好,現在仔細聽我說,按順序一個接一個地拿起小圓紙片,反覆執行以下幾個規則:
1. 如果你拿著的是一個數,不多說,直接把它放進圓筒;
2. 如果你拿著的是一個運算子號,不要把它放進去。先從圓筒裡取出兩個數(當然是先取最上而的啦,筒很細的),然後處這兩個數作運算子號指定的運算,並把結果寫在一張新的紙片上,然後放進筒裡。比如你拿著的是“+”,你要依次取出“32”和“3”,讓它們相加,得“35”,把“35”寫在一張新紙片上(現在“34”和“12”可以扔掉了),並把這張新紙片放進圓筒。
當圓筒裡只有一個數時,你就可以停下來了,我猜這個數是20,沒錯,這就是這個運算式的值!
我們剛才操作的,其實就是一個“棧”,棧是一種資料結構,具有一個性質——後進先出(LIFO——Last Input First Output),你已經深有體會了,就像一摞盤子,你只能從最上面的開始取,放的時候也只能放在最上面。放進去的動作叫做“入棧”,取出來叫做“彈出”。以後你就可以把棧想像成一摞盤子,或是上面說的小圓筒和小紙片,棧就是這麼簡單!
逆波蘭運算式雖然看起來比較繁瑣,其實在電腦中很有用。電腦可不知道先乘除後加減,先括弧內後括弧外,它要把你輸入的式子變成逆波蘭運算式,它就可以不斷地執行上面兩個規則,直至把結果算出來告訴你。現在你可以親自在電腦上試試,試著編一個程式,讓它讀入一個逆波蘭運算式,然後讓它計算!
成功了嗎?如果你回答“是”,你可以接著思考另一個問題,對於7個元素的序列1 2 3 4 5 6 7,通過一個棧的處理後(比如1 2 3入棧,3 2彈出,4入棧,4彈出……如此等等),能得到多少種不同的排列?能得到4 3 5 2 1 7 6嗎?能得到3 2 4 5 7 1 6嗎?