Untuk menjelaskan rekursi , saya menggunakan kombinasi penjelasan yang berbeda, biasanya untuk keduanya mencoba:
- jelaskan konsepnya,
- jelaskan mengapa itu penting,
- jelaskan bagaimana cara mendapatkannya.
Sebagai permulaan, Wolfram | Alpha mendefinisikannya dalam istilah yang lebih sederhana daripada Wikipedia :
Ekspresi sedemikian rupa sehingga setiap istilah dihasilkan dengan mengulangi operasi matematika tertentu.
Matematika
Jika siswa Anda (atau orang yang Anda jelaskan juga, mulai sekarang saya akan mengatakan siswa) memiliki setidaknya beberapa latar belakang matematika, mereka sudah jelas mengalami rekursi dengan mempelajari seri dan gagasan tentang rekursif dan hubungan perulangan mereka .
Cara yang sangat baik untuk memulai adalah dengan mendemonstrasikan dengan seri dan mengatakan bahwa ini adalah tentang rekursi:
- fungsi matematika ...
- ... yang memanggil dirinya untuk menghitung nilai yang sesuai dengan elemen ke-n ...
- ... dan yang mendefinisikan beberapa batasan.
Biasanya, Anda mendapatkan "huh huh, whatev '" yang terbaik karena mereka masih tidak menggunakannya, atau lebih mungkin hanya mendengkur yang sangat dalam.
Contoh Pengodean
Untuk selebihnya, sebenarnya ini adalah versi terperinci dari apa yang saya sajikan di Addendum dari jawaban saya untuk pertanyaan yang Anda tunjuk tentang pointer ( permainan kata-kata buruk).
Pada tahap ini, siswa saya biasanya tahu cara mencetak sesuatu ke layar. Dengan asumsi kita menggunakan C, mereka tahu cara mencetak satu char menggunakan write
atau printf
. Mereka juga tahu tentang loop kontrol.
Saya biasanya menggunakan beberapa masalah pemrograman yang berulang dan sederhana sampai mereka mendapatkannya:
Faktorial
Factorial adalah konsep matematika yang sangat sederhana untuk dipahami, dan implementasinya sangat dekat dengan representasi matematisnya. Namun, mereka mungkin tidak mendapatkannya pada awalnya.
Huruf
Versi alfabet menarik untuk mengajar mereka memikirkan urutan pernyataan rekursif mereka. Seperti dengan pointer, mereka hanya akan melemparkan garis secara acak pada Anda. Intinya adalah untuk membawa mereka ke realisasi bahwa loop dapat dibalik dengan memodifikasi kondisi ATAU hanya dengan membalik urutan pernyataan dalam fungsi Anda. Di situlah pencetakan alfabet membantu, karena itu sesuatu yang visual bagi mereka. Cukup minta mereka menulis fungsi yang akan mencetak satu karakter untuk setiap panggilan, dan menyebut dirinya secara rekursif untuk menulis yang berikutnya (atau sebelumnya).
Penggemar FP, lewati fakta bahwa mencetak barang ke aliran output adalah efek samping untuk saat ini ... Jangan terlalu mengganggu front-FP. (Tetapi jika Anda menggunakan bahasa dengan dukungan daftar, jangan ragu untuk menggabungkan ke daftar di setiap iterasi dan hanya mencetak hasil akhir. Tapi biasanya saya mulai dengan C, yang sayangnya bukan yang terbaik untuk masalah dan konsep semacam ini) .
Eksponensial
Masalah eksponensial sedikit lebih sulit ( pada tahap pembelajaran ini). Jelas konsepnya persis sama dengan faktorial dan tidak ada kerumitan tambahan ... kecuali Anda memiliki banyak parameter. Dan itu biasanya cukup untuk membingungkan orang dan mengusir mereka pada awalnya.
Bentuknya sederhana:
dapat diekspresikan seperti ini dengan pengulangan:
Lebih keras
Setelah masalah-masalah sederhana ini ditunjukkan DAN diimplementasikan kembali dalam tutorial, Anda dapat memberikan latihan yang sedikit lebih sulit (tapi sangat klasik):
- The Fibonacci angka,
- The Greatest Divisor umum ,
- Masalah 8-Queens ,
- Game The Towers of Hanoi ,
- Dan jika Anda memiliki lingkungan grafis (atau dapat memberikan potongan kode untuk itu atau untuk keluaran terminal atau mereka sudah dapat mengaturnya), hal-hal seperti:
- Dan untuk contoh praktis, pertimbangkan menulis:
- algoritma traversal pohon,
- parser ekspresi matematika sederhana,
- permainan kapal penyapu ranjau.
Catatan: Sekali lagi, beberapa di antaranya sebenarnya tidak lebih sulit ... Mereka hanya mendekati masalah dari sudut yang persis sama, atau yang sedikit berbeda. Tetapi latihan menjadi sempurna.
Pembantu
Referensi
Beberapa bacaan tidak pernah sakit. Yah itu pada awalnya, dan mereka akan merasa lebih tersesat. Ini adalah jenis hal yang tumbuh pada Anda dan yang ada di belakang kepala Anda sampai suatu hari Anda menyadari bahwa Anda akhirnya mendapatkannya. Dan kemudian Anda memikirkan kembali hal-hal yang Anda baca ini. The rekursi , rekursi dalam Ilmu Komputer dan hubungan pengulangan halaman di Wikipedia akan lakukan untuk saat ini.
Tingkat / Kedalaman
Dengan asumsi siswa Anda tidak memiliki banyak pengalaman pengkodean, sediakan kode bertopik. Setelah upaya pertama, berikan mereka fungsi pencetakan yang dapat menampilkan tingkat rekursi. Mencetak nilai numerik level membantu.
Diagram Stack-as-Drawers
Mengindentasi hasil cetak (atau output level) juga membantu, karena memberikan representasi visual lain tentang apa yang sedang dilakukan program Anda, membuka dan menutup konteks tumpukan seperti laci, atau folder dalam penjelajah sistem file.
Akronim Rekursif
Jika siswa Anda sudah sedikit berpengalaman dalam budaya komputer, mereka mungkin sudah menggunakan beberapa proyek / perangkat lunak dengan nama menggunakan akronim rekursif . Sudah menjadi tradisi untuk beberapa waktu, terutama dalam proyek-proyek GNU. Beberapa contoh termasuk:
Rekursif:
- GNU - "GNU's Not Unix"
- Nagios - "Nagios Tidak Akan Bersikeras Kesucian"
- PHP - "PHP Hypertext Preprocessor" (dan originall "Personal Home Page")
- Wine - "Anggur Bukan Emulator"
- Zile - "Zile Is Lossy Emacs"
Saling Rekursif:
- HURD - "HIRD of Unix-Replacing Daemon" (di mana HIRD adalah "HURD Antarmuka yang mewakili Kedalaman")
Mintalah mereka mencoba untuk membuat sendiri.
Demikian pula, ada banyak kejadian humor rekursif, seperti koreksi pencarian rekursif Google . Untuk informasi lebih lanjut tentang rekursi, baca jawaban ini .
Perangkap dan Pembelajaran Lebih Lanjut
Beberapa masalah yang biasanya dihadapi orang dan untuk itu Anda perlu tahu jawabannya.
Kenapa, oh Tuhan Kenapa ???
Kenapa kamu ingin melakukan itu? Alasan yang baik tetapi tidak jelas adalah bahwa seringkali lebih mudah untuk mengungkapkan masalah dengan cara itu. Alasan yang tidak terlalu bagus tapi jelas adalah bahwa sering kali mengetik kurang (jangan membuat mereka merasa begitu buruk hanya menggunakan rekursi ...).
Beberapa masalah pasti lebih mudah dipecahkan saat menggunakan pendekatan rekursif. Biasanya, masalah apa pun yang dapat Anda pecahkan menggunakan paradigma Divide and Conquer akan cocok dengan algoritma rekursi multi-cabang.
Apa N lagi ??
Mengapa saya n
atau (apa pun nama variabel Anda) berbeda setiap kali? Pemula biasanya memiliki masalah dalam memahami variabel dan parameter apa, dan bagaimana hal-hal yang disebutkan n
dalam program Anda dapat memiliki nilai yang berbeda. Jadi sekarang jika nilai ini ada di loop kontrol atau rekursi, itu bahkan lebih buruk! Bersikaplah baik dan jangan menggunakan nama variabel yang sama di mana-mana, dan jelaskan bahwa parameter hanyalah variabel .
Kondisi Akhir
Bagaimana cara menentukan kondisi akhir saya? Itu mudah, minta mereka mengatakan langkah-langkahnya dengan keras. Misalnya untuk faktorial mulai dari 5, lalu 4, lalu ... hingga 0.
Iblis ada di Rincian
Jangan berbicara dengan hal-hal awal tentang hal-hal seperti optimasi panggilan ekor . Saya tahu, saya tahu, TCO itu baik, tetapi pada awalnya mereka tidak peduli. Beri mereka waktu untuk membungkus kepala mereka di sekitar proses dengan cara yang bekerja untuk mereka. Jangan ragu untuk menghancurkan dunia mereka lagi nanti, tetapi beri mereka istirahat.
Demikian pula, jangan bicara langsung dari kuliah pertama tentang panggilan stack dan konsumsi memorinya dan ... well ... stack overflow . Saya sering mengajari siswa secara pribadi yang menunjukkan kepada saya ceramah di mana mereka memiliki 50 slide tentang semua yang perlu diketahui tentang rekursi ketika mereka hampir tidak dapat menulis satu lingkaran dengan benar pada tahap ini. Itu adalah contoh yang baik tentang bagaimana referensi akan membantu nanti tetapi saat ini hanya membuat Anda bingung .
Tapi tolong, pada waktunya, jelaskan bahwa ada alasan untuk menempuh rute berulang atau rekursif .
Rekursi Saling
Kami telah melihat bahwa fungsi dapat bersifat rekursif, dan bahkan mereka dapat memiliki beberapa titik panggilan (8-queens, Hanoi, Fibonacci atau bahkan algoritma eksplorasi untuk kapal penyapu ranjau). Tapi bagaimana dengan panggilan yang saling rekursif ? Mulai dengan matematika di sini juga. f(x) = g(x) + h(x)
di mana g(x) = f(x) + l(x)
dan h
dan l
hanya melakukan hal-hal.
Dimulai dengan hanya seri matematika membuatnya lebih mudah untuk menulis dan mengimplementasikan karena kontraknya didefinisikan dengan jelas oleh ekspresi. Misalnya, Urutan Hofstadter Wanita dan Pria :
Namun dalam hal kode, perlu dicatat bahwa implementasi solusi rekursif yang saling menguntungkan sering mengarah pada duplikasi kode dan lebih baik disederhanakan menjadi bentuk rekursif tunggal (Lihat Peter Norvig 's Solving Every Sudoku Puzzle .