切換
舊版
前往
大廳
主題

ZeroJudge - d285: 00727 - Postfix Expression 解題心得

Not In My Back Yard | 2018-10-19 10:29:46 | 巴幣 14 | 人氣 814

題目連結:


題目大意:
給定一個中序運算式,請轉成後序運算式,並輸出於一行。每筆輸出之間要空一行。

對於每個中序運算式,保證為合法的運算式,並且會以每一行一個字元輸入進來。每一個運算式最多占50行,每個運算式之前必定有一個空行。

運算元為一位數數字,且運算子都為二元運算子( + - * / )。運算子的優先順序為:先乘除,後加減,並由左至右運算,括號最先算。



範例輸入:
2
(
3
+
2
)
*
5

3
+
2


範例輸出:
32+5*

32+


解題思維:
首先,先理解「中序運算式」「後序運算式」到底是什麼:

「中序運算式」,即是我們一般會看見的運算式形式。例如:2+7 * 8,每個運算子都會被運算元所包圍(除非是一元運算子,或是括號)。

「後序運算式」,則是電腦方便運算的運算式形式。例如,上面的2+7 * 8的後序運算式為278 * +。而在生成後序運算式時,各個運算子的運算順序已經被考慮進去(包含括號),因此在裡面不會再看到括號的存在。

可是為何有中序、後序之差?這是因為,每個運算式都可化為一個樹,以上面的2+7 * 8為例,可化為:
如上圖,是一個二元樹(每個節點最多兩個子樹)。

我們常見的「中序運算式」便是這棵樹經由「中序探訪」的「路徑」。先走左子樹,接下來是自己,最後再走右子樹。

相似地,「後序運算式」為這棵樹的「後序探訪」。先走左子樹、再右子樹,最後才走根節點。



而中序轉後序不需要真的建一棵二元樹,再用後序探訪找路徑。只需要堆疊,在輸入的時候即可轉變成後序運算式。

以5+7-8 /(6+2)* 2為例:
先讀入5,一讀入數字即可把它放進後序運算式的結果之中。現結果為5,堆疊為空。

讀入+,放進堆疊裡。現結果為5,堆疊裡有+。

讀入7,結果為57,堆疊裡有+。

讀入-,判斷堆疊的頂端元素的優先順序,是否大於等於現在讀入的運算子之優先度。如果是,就一直把堆疊的頂端元素拿出,直到堆疊為空或是不符合為止。最後再放入現有的運算子。現結果為57+,堆疊裡有-。

讀入8,結果為57+8,堆疊裡有-。

讀入 / ,結果為57+8,堆疊裡有- / 。

讀入(,左括號很特別,要與右括號配對。結果為57+8,堆疊裡有- / (。

讀入6,結果為57+86,堆疊裡有- / (。

讀入+,結果為57+86,堆疊裡有- / (+。

讀入2,結果為57+862,堆疊裡有- / (+。

讀入),把堆疊的頂端元素拿出,直到遇見(。現結果為57+862+,堆疊裡有- / 。

讀入 * ,結果為57+862+ / ,堆疊裡有- * 。

讀入2,結果為57+862+ / 2,堆疊裡有- * 。

最後把堆疊清空,最終結果即為57+862+ / 2 * -,即是題目所求。


此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

我覺得可以
2018-10-19 19:06:13
Function
教學思路清晰,感謝版主
2023-06-08 21:30:24

更多創作