堆疊應用

中序、前序、後序運算式

本投影片含有強烈不專業成份
如服用時有過敏不適等症狀
請立即停用並找專業教師治療矯正

運算式?

  • 是一種義式咖啡描述方式

  • 用來描述如何進行運算

  • 由運算子與運算元組成

  • 運算式可以成為別的運算式的運算元

生活中很常見

  • 55 + 5 + 30 
    [香米蝦三明治飲料換熱咖啡加一個沙拉]

  • 35 + 35 * 0.6
    [飲料第二件六折]

  • ( 25 + 28 ) * 0.79
    [麵包任兩件七九折]
  • 1000 - ( (25 + 28) * 0.79 )
    [例外: 手上只有大鈔的時候]

中序運算式

  • 像前述運算子在運算元中間的運算式

  • 因為運算式可以是運算子

  • 35 + 35 * 0.5其實可以被解釋成

  • ( 35 + 35 ) * 0.5 或 35 + ( 35 * 0.5 )

優先度

  • 為了可以明確辨別上開情狀

  • 運算子被定義了執行順序
    [先乘除後加減]

  • 使用括號把運算式隔離開

  • Human Brain Friendly, But.......

從運算式下手

  • 過多括號隔離讓運算式看起來雜亂

  • 會混淆是因為運算式展開後有可能無法判斷運算子原本屬於哪個運算式
    [A /B -> A / B' + B'' -> 我們......回不去了]

  • 讓運算子不再陷入腳踏兩個式的狀態

前序與後序

中序 前序 後序
( 3 + 5 ) * 8 | * + 3 5 8 | 3 5 + 8 * |
3 + ( 5 * 8 ) | + 3 * 5 8 | 3 5 8 * + |

有點違反直覺啊

  • 直覺其實是被訓練出來的
  • 換個方式看它
    + 3 5 ->
    + 3 * 5 8 ->
    * + 3 5 8 ->
f(3, 5)
f(3,5)
f(3, f'(5, 8))
f(3,f(5,8))
f'(f(3, 5), 8)
f(f(3,5),8)

中序如何轉成後序

  • 一個重點是怎麼拆分運算式

  • 另一個重點是怎麼給定順序

拆分運算式

  • 循序解析運算式中的元素

  • 分辨是否為運算子或括號,不是則視為運算元

  • 如果遇到下一個運算子,需判斷是否上個運算式已結束,或上一個運算元需要跟隨的是這個運算子
    [優先順序的處理]

  • 遇到括號就以子運算式的方式處理

決定順序

  • 因為轉換時只有運算子受影響,運算元仍照原順序

  • 如果遇到運算子需先暫存,等到算式結束將其取出
    [算式結束的定義是暫存中的運算子有配到兩個運算元,並沒有被下個運算子所影響]

  • 如果遇到下一個運算子是有較高優先順序的,亦需將此運算子暫存,待算式結束時照後加的運算子先取出

  • 如果遇到左括號將其暫存,之後照前述動作,直到遇到右括號,將所有新增暫存取出直到左括號

  • 後加入的運算子先取出似乎符合堆疊的特性

後序如何進行運算

  • 依照後序的特性,循序走運算式

  • 因為要取的是運算元的值,需將運算元暫存

  • 遇到第一個運算子時一定有可以被運算的運算式,且前兩個元素一定是這個運算式的運算元

  • 根據運算式可以是別的運算式的運算元的特性,將運算結果當成運算元回存

  • 反覆同樣動作直到算式結束
    [算式結束的定義為已沒有下一個元素]

前序呢?

  • 讓我們把它放進記憶的堆疊裡吧

StackXfixExpression

By Ted Wu

StackXfixExpression

  • 1,669