Re: [問題] 請問大家都怎麼教別人遞迴和迴圈的基本 …

看板C_and_CPP作者 (眠月)時間13年前 (2011/06/23 00:26), 編輯推噓19(19013)
留言32則, 24人參與, 最新討論串2/5 (看更多)
※ 引述《leeyinf (貓貓)》之銘言: : 我有認識的朋友大學是非資訊(財金)相關科系畢業, : 最近對寫程式有興趣, : 可是她一直卡在遞迴和迴圈,這個部分... : 我教了可是她還是不太理解, 要學會遞迴很簡單的, 只要滿足兩個條件,她就可以很輕鬆的學會, 第一個條件就是不要教她迴圈, 第二個條件就是虐待她哈哈哈。 首先,叫她寫一個函數叫作 bool f(int max),可以印出 "10", 但是如果輸入的 max 小於 10,就什麼都不印, 如果有印東西的話,傳回 true,沒印東西的話,傳回 false。 這個函數很簡單,她應該可以毫無障礙的寫出來。 然後,叫她寫一個函數叫作 bool g(int max),可以印出 "9" 跟 "10", 但是如果輸入的 max 小於 9,就什麼都不印, 如果有印東西的話,傳回 true,沒印東西的話,傳回 false。 這個函數很簡單,她應該可以毫無障礙的寫出來。 然後,叫她寫一個函數叫作 bool h(int max),可以印出 "8", "9", "10", 但是如果輸入的 max 小於 8,就什麼都不印, 如果有印東西的話,傳回 true,沒印東西的話,傳回 false。 這個函數很簡單,她應該可以毫無障礙的寫出來。 然後,叫她寫一個函數叫作 bool i(int max),可以印出 "7" "8" "9" "10", 但是如果輸入的 max 小於 7,就什麼都不印, 如果有印東西的話,傳回 true,沒印東西的話,傳回 false。 這個函數很簡單,她應該可以毫無障礙的寫出來。 然後,叫她寫一個函數叫作 ...... 就這樣,虐待她寫完十個函數。 如果這個時候她腦袋清楚,而且沒有惱羞成怒的話, 你會發現她可能已經開始複用她的程式碼,在 f() 裡面呼叫 g(), g() 裡面呼叫 h(), h() 裡面呼叫 i(), i() 裡面呼叫 j()... 如果她沒有這麼做的話,你要提示她,讓她重複使用她的程式碼。 而且每寫好一個函數,都要進行編譯跟測試, 嘗試呼叫每一個函數,檢查一下行為是否正確。 等她寫完十個函數 f, g, h, i, j, k, l, m, n, o,印出 1 到 10 之後, 你問她能不能理解這些函數在做什麼,應該是可以, 因為每個函數都呼叫別人,這對於一般人來說不會有任合理解上的障礙。 然後你跟她說,使用者可能會希望印出來的東西是可以控制的, 不一定都是 10 9 8 7 ...,可能也希望會是 20 19 18 17 ... 請他把這十個函數,加上一個參數 a,函數原型變成 bool f(int a, int max)。 等她把十個函數都改完以後, 問她:「你會不會覺得這十個函數作的事情根本一模一樣?」(廢話) 「會阿 ^^"」 「o() 跟 m() 根本一模一樣對吧? 雖然 o() 呼叫的是 m(), m() 呼叫的是 n(), 好像不一樣, 但是因為 m() 跟 n() 根本一模一樣, 所以其實 o() 跟 m() 還是一樣,對吧?」 「對耶~」 「那既然一樣,你把 o() 裡面呼叫的 m(),改成 o()。」 然後編譯,測試,發現結果完全正確。 「你有沒有發現其實 f() 到 o() 根本都是同一個函數,只是名字不同。 就像寫了十個函數叫作 f1(), f2(), f3(),但是只有名字不一樣, 那既然作的事情都一樣,那我們只需要寫一次就好啦。」 然後請她把 f() 到 m() 全部刪掉。 而剩下的那個 o(a, max) 就是可以從 a 印到 max 的遞迴函數。 「所以遞迴其實很簡單, 你不要想成自己呼叫自己,你把她想成每個函數都呼叫別的函數, 只是這每一個函數的內容都一模一樣, 那既然一樣,我們就只需要寫一次,這樣有懂嗎?」 「有 ^O^ 你好聰明喔,好帥喔,明天我要嫁給你啦~明天我要嫁給你拉~」 == 個人經驗是「自己呼叫自己」對很多人來說就像是一個魔障一樣,無論如何無法跨越, 但是每一個已經學會函數的人,對於「自己呼叫別人」都可以毫無障礙的理解, 所以我覺得教遞迴的最好方法就是完全不要提到「自己呼叫自己」, 而是跟他說每個人都是呼叫別人,只是每個函數的實作內容都一模一樣, 我發現這樣講很多人都可以很簡單的吸收。 呼叫函數就是呼叫函數,呼叫的是自己還是別人根本沒有差。 所以最好讓他們在不知道什麼是「遞迴」的狀態下就寫出遞迴, 然後才跟他們說這叫作遞迴。 所以另外一個教法是使用「間接遞迴」, 可以設計一個誘導教程,讓 f() 用到 g(),然後 g() 會用到 f(), 然後再請對方把 f() 裡面的 g() 用 g() 的時作取代掉取代, 這樣 g() 就會消失,只留下 f() 呼叫 f()。這個時候再跟他說這就是遞迴。 不過我一下想不到怎麼設計小巧的題目作到這件事 = = 而且我覺得不會迴圈的人特別容易善用遞迴, 因為對他來說能重複做事情的唯一方法就是遞迴, 但是很多人都已經會了迴圈還要學遞迴,就有點可惜。 機會難得,好好把握。 -- To iterate is human, to recurse, divine. 遞迴只應天上有, 凡人該當用迴圈.   L. Peter Deutsch -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.160.113.219

06/23 00:34, , 1F
這真的不推不行
06/23 00:34, 1F

06/23 00:37, , 2F
有 ^O^ 你好聰明喔,好帥喔 明天繼續幫我修電腦好嗎 學長
06/23 00:37, 2F

06/23 00:40, , 3F
yoco 好強 !!
06/23 00:40, 3F

06/23 00:46, , 4F
我覺得從高中數學 數列級數講就好 f(n) = n + f(n-1)
06/23 00:46, 4F

06/23 00:48, , 5F
有些程式語言是沒有迴圈的 ex.Scheme 只能用recursive
06/23 00:48, 5F

06/23 00:48, , 6F
Hi Hi Yoco
06/23 00:48, 6F

06/23 00:49, , 7F
帥哥,你人真好:)
06/23 00:49, 7F

06/23 00:53, , 8F
收穫良多!!!!
06/23 00:53, 8F

06/23 00:56, , 9F
leeyinf 快嫁給我阿
06/23 00:56, 9F

06/23 01:06, , 10F
新板標GET!
06/23 01:06, 10F

06/23 01:35, , 11F
恭喜好人超
06/23 01:35, 11F

06/23 01:44, , 12F
慶祝新板標 再推一個
06/23 01:44, 12F

06/23 01:51, , 13F
澄清一下我不是帥哥 附上真相 http://tinyurl.com/42a46y6
06/23 01:51, 13F

06/23 01:58, , 14F
yoco大真是強, 還是個大正姐:) 順便賀j大抓到交替XD
06/23 01:58, 14F

06/23 02:11, , 15F
yoco好迷人喔(羞)
06/23 02:11, 15F

06/23 02:57, , 16F
有正有推。還是再說一下好可怕的抓交替版噢 >___<
06/23 02:57, 16F

06/23 07:13, , 17F
yoco應該出書或當老師的..
06/23 07:13, 17F

06/23 10:06, , 18F
yoco大人正真好!
06/23 10:06, 18F

06/23 13:20, , 19F
遞迴就是..鳴人做了一件事..叫鳴人再做那件事一次..
06/23 13:20, 19F

06/23 13:21, , 20F
yoco大正姐...>////<
06/23 13:21, 20F

06/23 13:26, , 21F
void f(){從前有個老和尚和小和尚,老和尚有天對小和尚
06/23 13:26, 21F

06/23 13:26, , 22F
說:「f()」;}最後這故事的結束是stck ov,樓上指這嗎?
06/23 13:26, 22F

06/23 13:28, , 23F
那如果叫鳴人肛了鳴人......
06/23 13:28, 23F

06/23 13:37, , 24F
...樓上冷靜點
06/23 13:37, 24F

06/23 14:56, , 25F
樓上上 LOL
06/23 14:56, 25F

06/23 20:01, , 26F
yoco大人正真好!
06/23 20:01, 26F

06/23 20:11, , 27F
=.="
06/23 20:11, 27F

06/23 22:23, , 28F
照片是王心怡吧
06/23 22:23, 28F

06/28 13:20, , 29F
大推
06/28 13:20, 29F

07/01 00:46, , 30F
朝聖
07/01 00:46, 30F

07/01 19:25, , 31F
朝聖 +1
07/01 19:25, 31F

07/06 21:35, , 32F
朝聖
07/06 21:35, 32F
文章代碼(AID): #1E0XUcaN (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1E0XUcaN (C_and_CPP)