b97902HW 板


LINE

  「遞迴只應天上有,凡人該當用迴圈。」   是如此一句浪漫的話語,激起高中幾位朋友追逐遞迴最終奧義的熱情。猶記得當年, 趁著夕陽將影子拉至最長的短暫片刻,在校園操場我們共同用黑影在草地上畫出了象徵青 春與冒險的字樣:Recursion。(故事後來寫成小說,詳見維基 http://0rz.tw/0a4Yf)   再說下去就太拖戲了。                   -   首先先來談函式,一個特定的函式用來解決特定的問題。像是以下函數的功能即為讀 入兩個整數 a 和 b,將兩者相加後再減去兩者兩減,並回傳給呼叫他的人: int fun1(int a,int b){ return (a+b)-(a-b); } main(){ int c; c=fun1(38,19); } 結束後 c 的值為 38。當然啦,函數非常的有用,再多舉幾個請自行判斷其用途: int fun2(int a,int b){ int fun3(int x){ void fun4(int num){ if(a>b) if(x>0) printf("Hello, I'm "); return a; return x; printf("%d ",num); return b; return -x; printf("years old."); } } }                   -   遞迴則是在函數尚未結束之前,又在函數內部呼叫了函數自己。原則上遞迴用來解決 結構類似的問題,許多情況下也可以看作把一個大問題切割成許多小問題並分別解決。   直接看例子幫助了解,拿最簡單的來講,要計算 1+2+3+...+n 的值。 方法一(迴圈): #include <cstdio> #include <cstdlib> main(){ int n,sum,i; scanf("%d",&n); sum=0; for(i=1;i<=n;i++) sum+=i; printf("sum=%d\n",sum); system("PAUSE"); } 方法二(遞迴):   先來觀察我們的問題,要求的東西是從 1 累加到 n 的值。因此可以定義一個函式, 用來計算我們要的答案(即 1+2+...+n),而影響這個函式的是究竟要加到多少才停止, 也就是輸入中的 n,於是我們傳入函數的參數為 n。 int calc(int n){ //不會寫... } 再來,考慮要如何解決 1+2+...+n 的問題。 { 1+2+3+...+(n-1)+n } = { 1+2+3+...+(n-1) } + n 原諒我的表達能力。我的意思是,要求 1 加到 n,我們可以先算出 1 加到 n-1 的 值,最後再多加一個 n 就是答案了,因此函式為: int calc(int n){ int ans; //先用 calc(n-1) 算出 1+...+n-1,最後再加 n ans=calc(n-1)+n; //在這裡你可以假設 calc(n-1) 會正確算出結果 return ans; //回傳答案 } 還沒結束,得再繼續努力。試試看計算 1+2+3 會發生什麼事: calc(3) = calc(2)+3 = calc(1)+2+3 = calc(0)+1+2+3 = calc(-1)+1+2+3 = ... 遞迴不會結束!這裡帶出了遞迴非常重要的一件事情,那就是結束條件。加總問題的 結束條件其實很容易,即當 n = 1 時代表 1+...+1 答案為 1,這樣遞迴就完成了。 #include <cstdio> #include <cstdlib> int calc(int n){ if(n==1) return 1; return calc(n-1)+n; } main(){ int n,sum; scanf("%d",&n); printf("sum=%d\n",calc(n)); system("PAUSE"); } 故事告訴我們,遞迴有兩件非常重要的事情: ‧遞迴式 :本例中 f(n) = f(n-1) + n ‧結束條件:本例中 f(n) = 1,當 n = 1 事實上,只要能寫出遞迴式和結束條件,要寫好遞迴函數就不是件困難的事情。國中 或高中時有個有名的數列叫 Fibonacci 數列,接下來以此為例: ‧遞迴式 :fib(n) = fib(n-1) + fib(n-2) ‧結束條件:fib(1) = fib(2) = 1 寫完兩大要素後,馬上就能完成相對應的 code(請別輸入太大的 n): #include <cstdio> #include <cstdlib> int fib(int n){ if(n==1 || n==2) //這裡是結束條件 return 1; return fib(n-1)+fib(n-2); //這裡是遞迴式 } main(){ int n; scanf("%d",&n); printf("The n-th Fibonacci number is %d\n",fib(n)); system("PAUSE"); } 甚至求組合數也是輕而易舉: ‧遞迴式 :C(n,k) = C(n-1,k) + C(n-1,k-1) ‧結束條件:C(n,k) = 0,當 n < k C(1,k) = 1 C(n,0) = 1 #include <cstdio> #include <cstdlib> int Combi(int n,int k){ if(n<k) return 0; if(n==1 || k==0) return 1; return Combi(n-1,k)+Combi(n-1,k-1); } main(){ int n,k; scanf("%d %d",&n,&k); printf("C(%d,%d) = %d\n",n,k,Combi(n,k)); system("PAUSE"); }                   - 最後再強調一次,遞迴通常用來解決結構相似的問題。而遞迴確實是比較不容易了解 的概念,多試幾次,並拿不同的東西寫寫看(例如求階乘)或許就能夠體會了。 實際練習一題不簡單但也不會太難的問題。答案下一篇再講,休息一下。 Question:將一正 n 邊形分割成 n-2 個三角形,有幾種分割方法? Sample Input Sample Output 4 2 分割方法見圖: 5 5 6 14 http://0rz.tw/cb4TF 7 42 8 132 9 429 10 ???? -- 沒有仔細校稿也沒有套色,請多見諒。 --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.242.109
1F:推 csftwpt5566:5566 友情推 10/09 14:54
2F:推 anfranion:我看到推文 笑了XDDD 10/09 14:59
3F:推 godgunman:看這個數列先猜Catalan !! (實際上就是阿..) 10/09 15:00
4F:推 cocohaha: 5566 資工推 10/09 15:01
5F:推 ggm5566: 5566 友情推 10/09 15:05
6F:推 r44: 5566 友情推 10/09 18:47
7F:推 LoganChien:推! 「遞迴只應天上有,凡人該當用迴圈」 10/09 21:59
8F:推 vanillaXleft:機車-.-都不照顧長id 還是推啦 10/09 22:01
9F:→ LoganChien:最後一題是 2007 年 IOI 選訓初試的題目? 10/09 22:01
10F:→ LoganChien:(小聲問:可以預告一下遞迴 II 嗎...) 10/09 22:04
11F:→ iForests:當然是「遞迴 II:魔力遞迴」,講 Cut 和使徒四這樣吧 10/09 22:06
12F:推 godgunman:那 給我給我 10/09 22:07
13F:→ iForests:自己去拿吧,我把一切都放在那裡了 10/09 22:09
14F:→ iForests:好我要回屏東了,魔力遞迴交棒給 godgunman 10/09 22:10
15F:→ iForests:再多說一點,多唱這首歌就可以體會所謂 Cut 的奧義: 10/09 22:21
16F:→ iForests:http://tw.youtube.com/watch?v=3OVUSCQwCX8 10/09 22:21
17F:推 csftwpt5566:這首是 56 經典名曲 The First Cut Is The Deepest 啊 10/09 22:27
18F:推 LoganChien:那我來寫「當數學歸納法遇上遞迴」好了 10/09 22:43







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:BuyTogether站內搜尋

TOP