標籤:出錯 產生 數學 代碼 程式 blog 故事 傳遞 編程模型
引子
從前有座山,山上有座廟,廟裡有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裡有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裡有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裡有個老和尚,老和尚在給小和尚講故事,故事講的是從前有座山,山上有座廟,廟裡有個老和尚,老和尚在給小和尚講故事,故事講的是......
這個例子,如果用java程式來示範,會是這個樣子:
public class Hello { public static void main(String[] args) { sayStory(); } static void sayStory(){ System.out.println("從前有座山,山上有座廟,廟裡有個老和尚,老和尚在給小和尚講故事,故事講的是"); sayStory(); } }
程式運行結果:
故事在一直講下去。
看一下java代碼中,在方法sayStory()中又調用了sayStory()。
遞迴概述什麼是遞迴
遞迴,英文為Recursion, 在電腦科學中,遞迴指得是在函數的定義中使用函數自身。
遞迴,包含了兩個意思:遞 和 歸。遞是只傳遞下去,歸是指歸來,也就是說,遞迴有去也有回。
那麼,上面的講故事的程式,算遞迴程式嗎?
在方法sayStory()中又調用了sayStory(),符合遞迴的一個條件,即傳遞,但是,這個程式,沒有歸來,所以,程式會一直運行下去,直到資源耗盡,程式出錯:
因此,這不是個完整的遞迴程式。
遞迴要素
首先,遞迴必須要申明一個函數,且在函數中調用自身。
另外,遞迴要有明確的終止條件,遞迴就是有去有回,必然有一個明確的重點,到達這個終點後,就不再往下遞,而是開始往迴歸來。
遞迴的內涵
? 遞迴的核心思想,就是把規模大的問題轉化為規模小的相似的子問題來解決。在函數實現時,因為解決大問題的方法和解決小問題的方法往往是同一個方法,所以就產生了函數調用它自身的情況,這也正是遞迴的定義所在。
考慮一下,遞迴的數學模型,很像數學歸納法。數學歸納法適用於將解決的原問題轉化為解決它的子問題,而它的子問題又變成子問題的子問題。歸納法解決數學問題一般分為下面3個步驟:
1:步進運算式:問題演算成子問題的運算式
2:結束條件:什麼時候可以不再使用步進運算式
3:求解運算式:在結束條件下能夠直接計算傳回值的運算式
比如,斐波那契數列,使用數學歸納法,3個步驟為:
1: 推匯出計算運算式: F(n)=F(n-1)+F(n-2) (n≥3)
2:結束條件:n=1,n=2時
3:求解運算式: F(1)=F(2)=1
遞迴的編程模型
明確了遞迴的數學模型後,我們就要看,如果通過編程來實現遞迴。一般的,有兩種編程模型:
模型一: 先處理問題,然後再往下傳遞
遞迴函式(大規模){
if (end_condition){ // 遞迴終止條件
end;
}else{
solve; // 處理問題
遞迴函式(小規模); // 分解問題規模,傳遞下去
}
}
模型二: 在歸來的過程中處理問題
遞迴函式(大規模){
if (end_condition){ // 遞迴終止條件 end; }else{ 遞迴函式(小規模); //分解問題規模,傳遞下去 solve; // 歸來,處理問題 }}
下面,示範一下,使用遞迴的編程模型,解決斐波那契數列問題。
首先,需要什麼一個函數,問題規模為n,問題的結果為一個整數。
則函數可以聲明為:int fib(int n)
然後,確定終止條件: n=1,n=2時
3:求解運算式:
F(n)=F(n-1)+F(n-2) (n≥3)
F(1)=1,F(2)=1
則代碼如下:
案例示範階乘
階乘n!的數學定義: n!=1234…..(n-1)n,並規定 1!=1。
因此,2!=21=2(1!),3!=3(21)=3(2!),
4!=4(321)=4(3!)
5!=5(4321)=54!
根據規律,可以推斷出: n!=n*(n-1)!,這就是階乘的遞迴公式。
並且可以明確遞迴的終止條件n=1,終止時的值為1。
下面,想一下,如何用java程式來實現呢?
遞迴函式原型,可以什麼為:int factorial(int n);
則函數的遞迴調用運算式為: factorial(n)=n* factorial(n-1)
具體代碼如下:
public class Hello { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請輸入n:"); int n = sc.nextInt(); int f = factorial(n); System.out.println("結果是:" + f); } static int factorial(int n) { if (n == 1) return 1; else return n * factorial(n - 1); }}
更多案例,請看下一章節。
源碼、更多資深講師相關課程資料、學習筆記請入群後向管理員免費擷取,更有專業知識答疑解惑。入群即送價值499元線上課程一份。
QQ群號:560819979
敲門磚(驗證資訊):高山流水
遞迴原來可以so easy