Pemahaman moden tentang rekursi: definisi kefungsian dan akses kepadanya dari luar dan dari kefungsian ini. Adalah dipercayai bahawa rekursi dilahirkan oleh ahli matematik: pengiraan faktorial, siri tak terhingga, fraktal, pecahan berterusan … Walau bagaimanapun, rekursi boleh didapati di mana-mana. Undang-undang semula jadi objektif "menganggap" rekursi sebagai algoritma utamanya dan bentuk ekspresi (kewujudan) bukan begitu banyak objek dunia material, tetapi secara amnya algoritma pergerakan utama.
Orang dari pelbagai kepakaran dalam pelbagai bidang sains dan teknologi menggunakan algoritma rekursif f (x), di mana "x ~/=f (x)". Fungsi yang memanggil dirinya sendiri ialah penyelesaian yang kukuh, tetapi membentuk dan memahami penyelesaian ini, dalam kebanyakan kes, tugas yang sangat sukar.
Pada zaman dahulu, rekursi digunakan untuk menambah ruang istana. Melalui sistem cermin yang diarahkan antara satu sama lain, anda boleh mencipta kesan spatial tiga dimensi yang menakjubkan. Tetapi adakah ia begitu mudah untuk memahami bagaimanalaraskan cermin ini? Lebih sukar untuk menentukan di mana satu titik dalam ruang, dipantulkan melalui beberapa cermin.
Rekursi, algoritma rekursif: makna dan sintaks
Masalah, yang dirumuskan dengan mengulangi urutan operasi, boleh diselesaikan secara rekursif. Algoritma mudah (mengira persamaan kuadratik, skrip untuk mengisi halaman web dengan maklumat, membaca fail, menghantar mesej…) tidak memerlukan pengulangan.
Perbezaan utama algoritma yang membenarkan penyelesaian rekursif:
- ada algoritma yang perlu dilaksanakan beberapa kali;
- algoritma memerlukan data yang berubah setiap masa;
- algoritma tidak perlu berubah setiap kali;
- ada syarat akhir: algoritma adalah rekursif - bukan tak terhingga.
Secara umum, tidak boleh dipertikaikan bahawa pelaksanaan sekali sahaja adalah syarat yang diperlukan untuk ketiadaan sebab pengulangan. Anda juga tidak boleh memerlukan syarat akhir wajib: rekursi tak terhingga mempunyai skopnya sendiri.
Algoritma adalah rekursif: apabila urutan operasi dilakukan berulang kali, pada data yang berubah setiap kali dan memberikan hasil baharu setiap kali.
Formula rekursi
Pemahaman matematik rekursi dan analognya dalam pengaturcaraan adalah berbeza. Matematik, walaupun terdapat tanda-tanda pengaturcaraan, tetapi pengaturcaraan adalah matematik yang lebih tinggi.
Algoritma yang ditulis dengan baik adalah seperti cermin intelek pengarangnya. Umumformula rekursi dalam pengaturcaraan ialah "f(x)", di mana "x ~/=f(x)" mempunyai sekurang-kurangnya dua tafsiran. Di sini "~" ialah persamaan atau ketiadaan hasil dan "=" ialah kehadiran hasil fungsi.
Pilihan pertama: dinamik data.
- fungsi "f(x)" mempunyai algoritma rekursif dan tidak boleh diubah;
- "x" dan hasil "f(x)" mempunyai nilai baharu setiap kali, hasil "f(x)" ialah parameter "x" baharu bagi fungsi ini.
Pilihan kedua: dinamik kod.
- fungsi "f(x)" mempunyai beberapa algoritma yang memperhalusi (menganalisis) data;
- analisis data - satu bahagian kod dan pelaksanaan algoritma rekursif yang melakukan tindakan yang diingini - bahagian kedua kod;
- hasil daripada fungsi "f(x)" bukan.
Tiada hasil yang normal. Pengaturcaraan bukan matematik, di sini hasilnya tidak perlu hadir secara eksplisit. Fungsi rekursif hanya boleh menghuraikan tapak dan mengisi pangkalan data, atau menjadikan objek mengikut input masuk.
Data dan rekursi
Memprogram algoritma rekursif bukan tentang mengira faktorial, di mana fungsi menerima setiap kali nilai yang diberikan iaitu satu lebih atau kurang daripada satu - pilihan pelaksanaan bergantung pada keutamaan pembangun.
Tidak kira berapa faktorial "8!",algoritma yang mematuhi formula ini dengan ketat.
Memproses maklumat ialah "matematik" dengan susunan yang berbeza sama sekali. Fungsi dan algoritma rekursif di sini beroperasi pada huruf, perkataan, frasa, ayat dan perenggan. Setiap tahap seterusnya menggunakan tahap sebelumnya.
Strim data input dianalisis dalam pelbagai keadaan, tetapi proses analisis biasanya rekursif. Tidak masuk akal untuk menulis algoritma unik untuk semua varian aliran input. Perlu ada satu fungsi. Di sini, algoritma rekursif ialah contoh cara membentuk aliran keluaran yang mencukupi untuk input. Ini bukan keluaran algoritma rekursif, tetapi ia adalah penyelesaian yang dikehendaki dan perlu.
Abstraksi, rekursi dan OOP
Pengaturcaraan berorientasikan objek (OOP) dan rekursi pada asasnya adalah entiti yang berbeza, tetapi ia saling melengkapi dengan sempurna. Abstraksi tidak ada kaitan dengan rekursi, tetapi melalui lensa OOP ia mewujudkan kemungkinan melaksanakan rekursi kontekstual.
Sebagai contoh, maklumat sedang dihuraikan dan huruf, perkataan, frasa, ayat dan perenggan diserlahkan secara berasingan. Jelas sekali, pembangun akan menyediakan untuk penciptaan contoh objek daripada lima jenis ini dan menawarkan penyelesaian algoritma rekursif pada setiap peringkat.
Sementara itu, jika pada peringkat huruf “tiada guna mencari makna”, maka semantik muncul pada peringkat perkataan. Anda boleh membahagikan perkataan kepada kata kerja, kata nama, adverba, preposisi… Anda boleh pergi lebih jauh dan mentakrifkan kes.
Di peringkat frasa, semantik ditambah dengan tanda baca dan logikgabungan perkataan. Pada peringkat ayat, tahap semantik yang lebih sempurna ditemui dan perenggan boleh dianggap sebagai pemikiran yang lengkap.
Pembangunan berorientasikan objek menentukan pewarisan sifat dan kaedah dan mencadangkan untuk memulakan hierarki objek dengan penciptaan moyang abstrak sepenuhnya. Pada masa yang sama, tidak syak lagi, analisis setiap keturunan akan menjadi rekursif dan tidak akan berbeza terlalu banyak pada peringkat teknikal dalam banyak kedudukan (huruf, perkataan, frasa dan ayat). Perenggan, seperti pemikiran lengkap, mungkin menonjol daripada senarai ini, tetapi ia bukanlah intipati.
Adalah penting bahawa bahagian algoritma yang luar biasa boleh dirumuskan pada peringkat nenek moyang abstrak, memperhalusinya pada tahap setiap keturunan dengan data dan kaedah yang dipanggil dari peringkat abstrak. Dalam konteks ini, abstraksi membuka ufuk baharu untuk pengulangan.
Ciri sejarah OOP
OOP telah datang ke dunia perisian dua kali, walaupun sesetengah pakar mungkin menonjolkan kemunculan pengkomputeran awan dan idea moden tentang objek dan kelas sebagai pusingan baharu dalam pembangunan teknologi IT.
Istilah "objek" dan "objektif" dalam konteks moden OOP biasanya dikaitkan dengan 50-an dan 60-an abad yang lalu, tetapi ia dikaitkan dengan 1965 dan kemunculan Simula, Lisp, Algol, Smalltalk.
Pada zaman itu, pengaturcaraan tidak begitu dibangunkan dan tidak dapat bertindak balas dengan secukupnya kepada konsep revolusioner. Perjuangan idea dan gaya pengaturcaraan (C / C ++ dan Pascal - kebanyakannya) masih jauh, dan pangkalan data masih dibentuk secara konsep.
Pada akhir 80-an dan awal 90-an, objek muncul dalam Pascal dan semua orang mengingati kelas dalam C / C ++ - ini menandakan pusingan baharu minat dalam OOP dan pada ketika itu alat, terutamanya bahasa pengaturcaraan, menjadi tidak hanya menyokong idea berorientasikan objek, tetapi berkembang dengan sewajarnya.
Sudah tentu, jika algoritma rekursif sebelum ini hanyalah fungsi yang digunakan dalam kod umum program, kini rekursi boleh menjadi sebahagian daripada sifat objek (kelas), yang menyediakan peluang menarik dalam konteks pewarisan.
Ciri OOP moden
Pembangunan OOP pada mulanya mengisytiharkan objek (kelas) sebagai koleksi data dan sifat (kaedah). Malah, ia adalah mengenai data yang mempunyai sintaks dan makna. Tetapi kemudiannya adalah tidak mungkin untuk mempersembahkan OOP sebagai alat untuk mengurus objek sebenar.
OOP telah menjadi alat untuk mengurus objek "sifat komputer". Skrip, butang, item menu, bar menu, tag dalam tetingkap pelayar ialah objek. Tetapi bukan mesin, produk makanan, perkataan, atau ayat. Objek sebenar kekal di luar pengaturcaraan berorientasikan objek dan alatan komputer telah menerima penjelmaan baharu.
Disebabkan perbezaan dalam bahasa pengaturcaraan popular, banyak dialek OOP telah muncul. Dari segi semantik, mereka secara praktikalnya setara, dan tumpuan mereka pada sfera instrumental, dan bukan pada yang digunakan, memungkinkan untuk mengambil perihalan objek sebenar di luaralgoritma dan memastikan "kewujudan" merentas platform dan merentas bahasa mereka.
Timbunan dan mekanisme panggilan fungsi
Mekanisme untuk memanggil fungsi (prosedur, algoritma) memerlukan penghantaran data (parameter), mengembalikan hasil dan mengingati alamat pengendali yang mesti menerima kawalan selepas fungsi (prosedur) selesai.
Biasanya, tindanan digunakan untuk tujuan ini, walaupun bahasa pengaturcaraan atau pembangun sendiri boleh menyediakan pelbagai pilihan untuk memindahkan kawalan. Pengaturcaraan moden mengakui bahawa nama fungsi bukan sahaja parameter: ia boleh dibentuk semasa pelaksanaan algoritma. Algoritma juga boleh dibuat semasa melaksanakan algoritma lain.
Konsep algoritma rekursif, apabila nama dan badannya boleh ditentukan pada masa pembentukan tugasan (memilih algoritma yang diingini), memperluaskan rekursif bukan sahaja kepada cara melakukan sesuatu, tetapi juga siapa sebenarnya yang sepatutnya lakukannya. Memilih algoritma dengan nama "bermakna" adalah menjanjikan, tetapi menimbulkan kesukaran.
Rekursif pada set fungsi
Anda tidak boleh mengatakan bahawa algoritma adalah rekursif apabila ia memanggil dirinya sendiri dan itu sahaja. Pengaturcaraan bukan dogma, dan konsep rekursif bukanlah keperluan eksklusif untuk memanggil diri anda daripada badan algoritma anda sendiri.
Aplikasi praktikal tidak selalu memberikan penyelesaian yang bersih. Selalunya, data awal mesti disediakan, dan hasil panggilan rekursif mesti dianalisis dalam konteks keseluruhan masalah (keseluruhan algoritma) dalamsecara keseluruhan.
Malah, bukan sahaja sebelum fungsi rekursif dipanggil, tetapi juga selepas ia selesai, program lain boleh atau harus dipanggil. Jika tiada masalah khas dengan panggilan: fungsi rekursif A() memanggil fungsi B(), yang melakukan sesuatu dan memanggil A(), maka serta-merta terdapat masalah dengan pengembalian kawalan. Setelah menyelesaikan panggilan rekursif, fungsi A() mesti menerima kawalan untuk memanggil semula B(), yang akan memanggilnya semula. Mengembalikan kawalan sebagaimana yang sepatutnya dalam susunan kembali ke B() ialah penyelesaian yang salah.
Pengaturcara tidak terhad dalam pilihan parameter dan boleh melengkapkannya dengan nama fungsi. Dalam erti kata lain, penyelesaian yang ideal adalah untuk menghantar nama B() kepada A() dan biarkan A() sendiri memanggil B(). Dalam kes ini, tiada masalah dengan mengembalikan kawalan dan pelaksanaan algoritma rekursif akan menjadi lebih telus.
Pemahaman dan tahap rekursi
Masalah dengan membangunkan algoritma rekursif ialah anda perlu memahami dinamik proses. Apabila menggunakan rekursi dalam kaedah objek, terutamanya pada tahap nenek moyang abstrak, terdapat masalah memahami algoritma anda sendiri dalam konteks masa pelaksanaannya.
Pada masa ini, tiada sekatan pada tahap fungsi bersarang dan kapasiti tindanan dalam mekanisme panggilan, tetapi terdapat masalah pemahaman: pada masa mana tahap data atau tempat mana dalam algoritma umum yang dipanggil rekursif fungsinya dan berapa banyak panggilan dirinya.
Alat penyahpepijatan sedia ada selalunya tidak berkuasaberitahu pengaturcara penyelesaian yang betul.
Gelung dan rekursi
Adalah dianggap bahawa pelaksanaan kitaran adalah bersamaan dengan rekursi. Malah, dalam beberapa kes, algoritma rekursif boleh dilaksanakan dalam sintaks binaan bersyarat dan kitaran.
Walau bagaimanapun, jika terdapat pemahaman yang jelas bahawa fungsi tertentu mesti dilaksanakan melalui algoritma rekursif, sebarang penggunaan luaran gelung atau pernyataan bersyarat harus ditinggalkan.
Maksudnya di sini ialah penyelesaian rekursif dalam bentuk fungsi yang menggunakan dirinya sendiri akan menjadi algoritma lengkap dan lengkap dari segi fungsi. Algoritma ini memerlukan pengaturcara untuk menciptanya dengan usaha, memahami dinamik algoritma, tetapi ia akan menjadi penyelesaian muktamad yang tidak memerlukan kawalan luaran.
Sebarang gabungan pengendali bersyarat dan kitaran luaran tidak akan membenarkan kami mewakili algoritma rekursif sebagai fungsi lengkap.
Konsensus Rekursi dan OOP
Dalam hampir semua varian membangunkan algoritma rekursif, rancangan timbul untuk membangunkan dua algoritma. Algoritma pertama menjana senarai objek masa hadapan (contoh), dan algoritma kedua sebenarnya ialah fungsi rekursif.
Penyelesaian terbaik ialah menyusun rekursi sebagai satu sifat (kaedah) yang sebenarnya mengandungi algoritma rekursif dan meletakkan semua kerja persediaan ke dalam pembina objek.
Algoritma rekursif hanya akan menjadi penyelesaian yang betul apabila ia berfungsihanya dengan dirinya sendiri, tanpa kawalan dan pengurusan luar. Algoritma luaran hanya boleh memberi isyarat untuk berfungsi. Hasil kerja ini sepatutnya merupakan penyelesaian yang diharapkan, tanpa sokongan luaran.
Rekursi hendaklah sentiasa menjadi penyelesaian tersendiri yang lengkap.
Pemahaman intuitif dan kesempurnaan fungsi
Apabila pengaturcaraan berorientasikan objek menjadi standard de facto, menjadi jelas bahawa untuk membuat kod dengan berkesan, anda perlu mengubah pemikiran anda sendiri. Pengaturcara mesti beralih daripada sintaks dan semantik bahasa kepada dinamik semantik semasa pelaksanaan algoritma.
Ciri pengulangan: ia boleh digunakan pada semua:
- mengikis web;
- operasi carian;
- menghuraikan maklumat teks;
- membaca atau mencipta dokumen MS Word;
- teg pensampelan atau menganalisis…
Ciri OOP: ia memungkinkan untuk menerangkan algoritma rekursif pada tahap nenek moyang abstrak, tetapi memperuntukkan ia merujuk kepada keturunan unik, yang setiap satunya mempunyai palet data dan sifatnya sendiri.
Rekursi sesuai kerana ia memerlukan kesempurnaan fungsi algoritmanya. OOP meningkatkan prestasi algoritma rekursif dengan memberikannya akses kepada semua kanak-kanak unik.