1.2 遞迴應用
輾轉相除法
輾轉相除法在求兩數的最大公因數(GCD),是一種非常有效率的方法,我們不需要分別找出每個質因數,就可以找到其最大公因數,以下以求330, 210兩數的最大公因數為例
- 如果以橫式來呈現除法過程會更容易看出輾轉的過程
- 被除數=除數$\times$商+餘數
- $330 = 210 \times 1 + 120$
- $210 = 120 \times + 90$
- $120 = 90 \times 1 + 30$
- $90 = 30 \times 3 + 0$
- 可以發現以下性質
- 前一回合的
除數是下一回合的被除數。 - 前一回合的
餘數是下一回合的除數。 - 若餘數為
0,則該回合的除數即為最大公因數。
- 前一回合的
- 最後,就可以藉由上述結果建立遞迴關係式 \[GCD(x, y)= \begin {cases} GCD(b, a \% b) & \text{if }a\% b!=0 \\ b & \text{if } a \% b == 0\end{cases}\]
- 遞迴函數程式碼
- Ex104輾轉相除法練習:網址
河內塔問題
問題介紹
典型的三圓盤河內塔,以下為規則
拆解問題
-
兩個圓盤:在兩個圓盤中,需要將中間
B柱當成緩衝區,須將最上面那一個圓盤先放置緩衝區,才可將最大的圓盤移至C柱 -
在此,發現了一個規律,在底層圓盤移動前,上方圓盤必須先全部搬到緩衝區
-
下一步,可建立一個函數
move(discs, from, buffer, to),discs為我們須將$1~discs$由from移到to -
換句話說,當$discs=1$時,代表不用在乎
buffer直接將目前的盤子從from移動到to即可 -
當 $n=1$ 時
-
move(1, A, , C)將1由A放置C - 完成
-
-
當 $n=2$ 時
-
move(2, A, B, C)-
move(1, A, , B) - 將在A柱中最下方圓盤移到C柱
-
move(1, B, , C)
-
-
-
當 $n = 3$ 時(上到下編號1、2、3)
-
藉由上方關係,可利用程式寫成一函數,程式碼如下
void move(int discs, char from, char buffer, char to) { if(discs==0) return; move(discs-1, from , to, buffer); printf("move disc %d from %c to %c\n", discs, from, to); move(discs-1, buffer, from, to); } -
Ex104河內塔:題目連結
快速冪
快速冪為快速計算$x^y$的方法,通常這個數字會很大,超過整數變數的範圍,所以會額外給你一個$p$,代表要對這個數字取$p$的餘數。換句話說,也就是給定$x, y, p$,要計算$x^y(\% p)$的結果









