2012年12月29日 星期六

運算式的介紹、轉換

X = A + B 就是一個運算式。
運算元就是英文字母、數字、變數(紅色部分)
運算子就是「+」、「-」、「*」、「/」…等(藍色部分)


依據「運算子」的位置,可分為:
  1. 前序式:「 AB
  2. 中序式:「A + B」,人類專用
  3. 後序式:「 AB +」,電腦專用
在運算式的轉換中有二種方法:
  1. 堆疊法
  2. 括號法
這裡我簡單介紹一下如何使用堆疊法
共通規則:
  • 讀到「英文字母」直接輸出;讀到「加減乘除、括號」就進堆疊
  • 「*」、「/」比「+」、「-」優先,如果不按照優先順序堆疊,就移動前面的字元到輸出區。
  • 讀取結束後若堆疊區還有東西,就依序移動到輸出區。

若是中序式轉後序式
  1. 從式子左邊開始讀取。
  2. 第二點較獨特,讀到「(」直接送進堆疊區;讀到「)」就在堆疊區內由上往下(或右往左)輸出直到遇見「 ( 」為止。
  3. 若堆疊區出現「*/」、「/*」、「-+」、「+-」 這種「優先順序相等的運算子黏在一起」的狀況,就移動前面的字元到輸出區
好,我知道你霧煞煞,來個例題吧:
利用堆疊法將中序式 ( A + B * C / D ) + F / G 轉為後序式,你可以先將題目抄起來。

 
※作法

我建議在紙上規劃出這樣的表格(可以是透明的沒關係)
步驟 讀取區 堆疊區 輸出區
       


那就開始啦
步驟 讀取區 堆疊區 輸出區
1 ( (  
2 A ( A
3 + (+ A
4 B (+ AB
5 * (+* AB
6 C (+* ABC
7 / (+*/ 變成 (+/ ABC*
8 D (+/ ABC*D
9 ) (+/) 變成 ( ) 再變成無 ABC*D/+
10 + + ABC*D/+
11 F + ABC*D/+F
12 / +/ ABC*D/+F
13 G +/ ABC*D/+FG
14 - - ABC*D/+FG/+



步驟 1
因為題目要中序式轉後序式,所以從式子的左邊 「(」 開始讀取,遵循第 2 點進堆疊

步驟 2
讀到英文字母「A」,輸出 A

步驟 3
讀到加減乘除符號「+」,進堆疊

步驟 4
讀到英文字母「B」,輸出 B

步驟 5
讀到加減乘除符號「*」,進堆疊

步驟 6
讀到英文字母「C」,輸出 C

步驟 7
讀到加減乘除符號「/」,進堆疊,遇到上述第 3 點的情況,怎麼辦?只要移動「/」的前面「*」到輸出區即可哦!所以目前輸出「ABC*」 。

步驟 8
讀到英文字母「D」,輸出 D

步驟 9
讀到括號「 ) 」,進堆疊,而又遇到上述第 2 點的情況,照堆疊順序搬移「(  )」內的運算子到輸出區,然後括號利用完就可以把它丟了(哈…)。

步驟 10
讀到加減乘除符號「+」,進堆疊,目前輸出「ABC*D/+」。

步驟 11
讀到英文字母「F」,輸出 F

步驟 12
讀到加減乘除符號「/」,進堆疊

步驟 13
讀到英文字母「G」,輸出 G

步驟 14
共同規則敘述,讀取結束,依序移動堆疊內容到輸出區,結果就是「ABC*D/+FG/+」 。

希望你沒掛…
接下來介紹中序式轉前序式

  1. 從式子右邊開始讀取。
  2. 跟剛才相反,讀到「 ) 」直接送進堆疊區;讀到「 ( 」就在堆疊區內由上往下(或右往左)輸出直到遇見「 ) 」為止。
  3. 又跟剛才相反,若堆疊區出現「*/」、「/*」、「-+」、「+-」 這種「優先順序相等的運算子黏在一起」的狀況,什麼都不用做
  4. 全部完成後,要反向輸出
一樣的例題哦!( A + B * C / D ) + F / G 轉前序式
步驟 讀取區 堆疊區 輸出區
1 G   G
2 / / G
3 F / GF
4 + /+ 變成 + GF/
5 ) +) GF/
6 D +) GF/D
7 / +)/ GF/D
8 C +)/ GF/DC
9 * +)/* GF/DC
10 B +)/* GF/DCB
11 + +)/*+ 變成 +)+ GF/DCB*/
12 A +)+ GF/DCB*/A
13 ( +)+( 變成 + GF/DCB*/A+
14 - - GF/DCB*/A++



步驟 1
因為題目要中序式轉序式,所以從式子的右邊 「G」 開始讀取,遵循共通規則輸出 G

步驟 2
讀到加減乘除符號「/」,進堆疊

步驟 3
讀到英文字母「F」,輸出 F

步驟 4
讀到加減乘除符號「+」,進堆疊,而遵循共同規則移動前面的字元到輸出區。

步驟 5
讀到運算子「 ) 」,也就是第 2 點,直接進堆疊。

步驟 6
讀到英文字母「D」,輸出 D

步驟 7
讀到加減乘除符號「/」,進堆疊

步驟 8
讀到英文字母「C」,輸出 C

步驟 9
讀到加減乘除符號「*」,進堆疊。什麼?你慌張?看看第 3 點

步驟 10
讀到英文字母「B」,輸出 B

步驟 11
讀到加減乘除符號「+」,進堆疊,而遵循共同規則移動前面的字元到輸出區,有兩次哦,一次做好後發現「+)/+」所以要再來一次。

步驟 12
讀到英文字母「A」,輸出 A

步驟 13
讀讀到運算子「 ( 」,第 2 點的狀況,進堆疊後由右往左輸出直到遇見「 ) 」

步驟 14
共同規則敘述,讀取結束,依序移動堆疊內容到輸出區,結果就是「GF/DCB*/A++」…錯啦,別忘了還要依循第 4 點,反向輸出!
所以結果是「++A/*BCD/FG」才對哦。

以上很簡單對吧?嗯?哈哈。
接下來介紹括號法,括號法更簡單哦,真的。
共通規則:
  • 左而右開始
  • 看到括號,先對它下手
  • 除優先處理、其次加、減

若是中序式轉後序式
  1. 加上括號後將運算子複製到「 ) 」的上面,以便於後續的工作。
  2. 輸出不管「 ( 」跟「運算子」只管「 ) 」跟英文字母
改用「A * ( B * C + E * F) / G」當例題,將其轉為後序式。


※作法

步驟 1 
在紙上寫下題目「A * ( B * C + E * F) / G」。

步驟 2 
我看到括號了哦,所以要對它先下手!不過要考慮優先順序從左邊開始

步驟 3 
乘、除優先,加上從左邊開始,所以「B * C」要加上括號,根據第一點敘述,把運算子「*」複製到「 ) 」上面


步驟 4 
乘、除優先,輪到「E * F」要加上括號,根據第一點敘述,把運算子「*」複製到「 ) 」上面


步驟 5
現在還是在括號內哦,依據優先順序所以輪到「(B * C) + (E * F)」要加括號,但是題目已經加了,所以就不用啦!下一步驟就是把運算子「+」複製到「 ) 」上面,由於這裡比較亂,我用黃色醒目來處理。


步驟 6
括號內處理完以後,再檢查看看還有無其他括號區。確認沒有後,由左而右慢慢加括號。所以就要將「A * ( ( B * C) + ( E * F ) )」加括號。


步驟 7 
一樣由左而右加括號,輪到「( * (( B * C) + ( E * F ) ) ) / G」。


步驟 8 
都 OK 了吧,依據第 2 點,因為是轉後序式所以不管「 ( 」,也不管「運算子」。只管「英文字母」跟「 ) 」。所以結果為「ABC*EF*+*G/」。

若是中序式轉序式
  1. 加上括號後將運算子複製到「 ( 」的上面,以便於後續的工作。
  2. 輸出不管「 ) 」跟「運算子」只管「 ( 」跟英文字母
整個就是跟「中序式後序式」相反哦
一樣用「A * ( B * C + E * F) / G」當例題喔。

※作法

步驟 1 
在紙上寫下題目「A * ( B * C + E * F) / G」。

步驟 2 
有括號!先弄它!!!

步驟 3 
乘、除優先,加上從左邊開始,所以「B * C」要加上括號,根據第一點敘述,把運算子「*」複製到「 ( 」上面


步驟 4 
一樣乘、除優先,所以「E * F」要加上括號,根據第一點敘述,把運算子「*」複製到「 ( 」上面


步驟 5 
現在還是在括號內,依據優先順序所以輪到「(B * C) + (E * F)」要加括號,但題目已經加好了,所以就免啦。把運算子「+」複製到「 ( 」上面即可。


步驟 6 
括號內處理完以後,再檢查看看還有無其他括號區。確認沒有後,由左而右慢慢加括號。所以就要將「* ( ( B * C) + ( E * F ) )」加括號。


步驟 7 
一樣由左而右加括號,輪到「( * (( B * C) + ( E * F ) ) ) / G」。


步驟 8 
依據第 2 點,因為是轉序式所以不管「 ) 」,也不管「運算子」。
只管「英文字母」跟「 ( 」。所以結果為「/*A+*BC*EFG」。

好了,所有有關運算式轉換都介紹完啦,若有任何錯誤的地方或是疑問,
非常歡迎您在底下留言哦,我都會看。

沒有留言:

張貼留言

發文前,請詳細填寫好讓我知道你是誰哦,拜託啦。