Modernong pag-unawa sa recursion: kahulugan ng functionality at access dito mula sa labas at mula sa functionality na ito. Ito ay pinaniniwalaan na ang recursion ay ipinanganak ng mga mathematician: factorial na pagkalkula, walang katapusang serye, fractals, patuloy na mga fraction … Gayunpaman, ang recursion ay matatagpuan sa lahat ng dako. Ang layunin ng mga natural na batas ay "isinasaalang-alang" ang recursion bilang kanilang pangunahing algorithm at anyo ng pagpapahayag (existence) hindi gaanong mga bagay ng materyal na mundo, ngunit sa pangkalahatan ang pangunahing algorithm ng paggalaw.
Ang mga tao ng iba't ibang speci alty sa iba't ibang larangan ng agham at teknolohiya ay gumagamit ng recursive algorithm na f (x), kung saan "x ~/=f (x)". Ang isang function na tinatawag ang sarili nito ay isang malakas na solusyon, ngunit ang pagbuo at pag-unawa sa solusyon na ito ay, sa karamihan ng mga kaso, isang napakahirap na gawain.
Noong sinaunang panahon, ginamit ang recursion upang madagdagan ang espasyo ng palasyo. Sa pamamagitan ng isang sistema ng mga salamin na nakadirekta sa isa't isa, maaari kang lumikha ng mga nakamamanghang three-dimensional spatial effect. Ngunit napakadali bang maunawaan kung paanoayusin ang mga salamin na ito? Mas mahirap matukoy kung nasaan ang isang punto sa kalawakan, na naaaninag sa maraming salamin.
Recursion, recursive algorithm: kahulugan at syntax
Ang problema, na nabuo sa pamamagitan ng pag-uulit ng pagkakasunod-sunod ng mga operasyon, ay maaaring malutas nang pabalik-balik. Ang isang simpleng algorithm (pag-compute ng quadratic equation, isang script para punan ang isang web page ng impormasyon, pagbabasa ng file, pagpapadala ng mensahe…) ay hindi nangangailangan ng recursion.
Mga pangunahing pagkakaiba ng algorithm na nagbibigay-daan sa isang recursive na solusyon:
- may algorithm na kailangang isagawa nang ilang beses;
- algorithm ay nangangailangan ng data na nagbabago sa bawat oras;
- ang algorithm ay hindi kailangang magbago sa bawat oras;
- may pangwakas na kundisyon: ang algorithm ay recursive - hindi infinite.
Sa pangkalahatan, hindi mapagtatalunan na ang isang beses na pagpapatupad ay isang kinakailangang kondisyon para sa kawalan ng dahilan para sa pag-uulit. Hindi ka rin maaaring humiling ng isang mandatoryong panghuling kundisyon: ang mga infinite recursion ay may sariling saklaw.
Ang algorithm ay recursive: kapag paulit-ulit na isinagawa ang isang sequence ng mga operasyon, sa data na nagbabago sa bawat oras at nagbibigay ng bagong resulta sa bawat pagkakataon.
Recursion formula
Ang pag-unawa sa matematika ng recursion at ang analogue nito sa programming ay iba. Ang matematika, bagama't may mga palatandaan ng programming, ngunit ang programming ay matematika ng mas mataas na pagkakasunud-sunod.
Ang isang mahusay na pagkakasulat na algorithm ay parang salamin ng talino ng may-akda nito. Heneralang recursion formula sa programming ay "f(x)", kung saan ang "x ~/=f(x)" ay may hindi bababa sa dalawang interpretasyon. Narito ang "~" ay ang pagkakatulad o kawalan ng resulta, at ang "=" ay ang presensya ng resulta ng function.
Unang opsyon: data dynamics.
- Ang function na "f(x)" ay may recursive at immutable algorithm;
- Ang "x" at ang resultang "f(x)" ay may mga bagong value sa bawat pagkakataon, ang resultang "f(x)" ay ang bagong "x" na parameter ng function na ito.
Ikalawang opsyon: code dynamics.
- Ang function na "f(x)" ay may ilang algorithm na nagpipino (nagsusuri) ng data;
- data analysis - isang bahagi ng code at ang pagpapatupad ng mga recursive algorithm na nagsasagawa ng gustong aksyon - ang pangalawang bahagi ng code;
- ang resulta ng function na "f(x)" ay hindi.
Walang resultang normal. Ang programming ay hindi matematika, dito ang resulta ay hindi kailangang tahasang naroroon. Ang isang recursive function ay maaari lamang mag-parse ng mga site at mag-populate sa database, o mag-instantiate ng mga bagay ayon sa papasok na input.
Data at recursion
Ang pagpo-program ng mga recursive algorithm ay hindi tungkol sa pagkalkula ng factorial, kung saan ang function ay tumatanggap sa tuwing may ibinigay na halaga na isa pa o mas mababa sa isa - ang opsyon sa pagpapatupad ay depende sa kagustuhan ng developer.
Hindi mahalaga kung gaano ang factorial na "8!",algorithm na mahigpit na sumusunod sa formula na ito.
Ang pagpoproseso ng impormasyon ay "matematika" ng isang ganap na naiibang pagkakasunud-sunod. Ang mga recursive function at algorithm dito ay gumagana sa mga titik, salita, parirala, pangungusap at talata. Ginagamit ng bawat susunod na antas ang nauna.
Ang input data stream ay sinusuri sa isang malawak na hanay ng mga kundisyon, ngunit ang proseso ng pagsusuri ay karaniwang recursive. Walang saysay na magsulat ng mga natatanging algorithm para sa lahat ng variant ng input stream. Dapat mayroong isang pag-andar. Dito, ang mga recursive algorithm ay mga halimbawa ng kung paano bumuo ng isang output stream na sapat sa input. Hindi ito ang output ng recursive algorithm, ngunit ito ang ninanais at kinakailangang solusyon.
Abstraction, recursion at OOP
Ang Object-oriented programming (OOP) at recursion ay sa panimula ay magkaibang entity, ngunit sila ay ganap na umakma sa isa't isa. Ang abstraction ay walang kinalaman sa recursion, ngunit sa pamamagitan ng lens ng OOP ay lumilikha ito ng posibilidad na ipatupad ang contextual recursion.
Halimbawa, ang impormasyon ay na-parse at ang mga titik, salita, parirala, pangungusap at talata ay hiwalay na naka-highlight. Malinaw, ang developer ay magbibigay para sa paglikha ng mga pagkakataon ng mga bagay ng limang uri na ito at mag-aalok ng solusyon ng mga recursive algorithm sa bawat antas.
Samantala, kung sa antas ng mga titik “walang kwenta ang paghahanap ng kahulugan”, lalabas ang mga semantika sa antas ng mga salita. Maaari mong hatiin ang mga salita sa mga pandiwa, pangngalan, pang-abay, pang-ukol… Maaari kang magpatuloy at tukuyin ang mga kaso.
Sa antas ng parirala, ang mga semantika ay dinadagdagan ng mga bantas at lohikamga kumbinasyon ng salita. Sa antas ng mga pangungusap, matatagpuan ang isang mas perpektong antas ng semantika, at maaaring ituring ang isang talata bilang isang kumpletong kaisipan.
Object-oriented development ay paunang tinutukoy ang pamana ng mga katangian at pamamaraan at nagmumungkahi na simulan ang hierarchy ng mga bagay sa paglikha ng isang ganap na abstract na ninuno. Kasabay nito, walang alinlangan, ang pagsusuri ng bawat inapo ay magiging recursive at hindi masyadong mag-iiba sa teknikal na antas sa maraming posisyon (mga titik, salita, parirala at pangungusap). Ang mga talata, tulad ng mga kumpletong kaisipan, ay maaaring maging kakaiba sa listahang ito, ngunit hindi sila ang esensya.
Mahalagang mabuo ang napakaraming bahagi ng algorithm sa abstract na antas ng ninuno, na pinipino ito sa antas ng bawat inapo gamit ang data at mga pamamaraan na tinatawag mula sa abstract na antas. Sa kontekstong ito, ang abstraction ay nagbubukas ng mga bagong abot-tanaw para sa recursion.
Mga makasaysayang feature ng OOP
Ang OOP ay dalawang beses na dumating sa mundo ng software, bagama't maaaring isa-isa ng ilang eksperto ang paglitaw ng cloud computing at mga modernong ideya tungkol sa mga bagay at klase bilang isang bagong yugto sa pagbuo ng mga teknolohiyang IT.
Ang mga terminong "object" at "objective" sa modernong konteksto ng OOP ay karaniwang iniuugnay sa 50s at 60s ng huling siglo, ngunit nauugnay ang mga ito sa 1965 at ang paglitaw ng Simula, Lisp, Algol, Smalltalk.
Noong mga panahong iyon, ang programming ay hindi partikular na binuo at hindi sapat na tumugon sa mga rebolusyonaryong konsepto. Ang pakikibaka ng mga ideya at istilo ng programming (C / C ++ at Pascal - karamihan) ay malayo pa, at ang mga database ay nabuo pa rin sa konsepto.
Noong huling bahagi ng dekada 80 at unang bahagi ng dekada 90, lumitaw ang mga bagay sa Pascal at naalala ng lahat ang mga klase sa C / C ++ - minarkahan nito ang isang bagong yugto ng interes sa OOP at noon na ang mga tool, pangunahin ang mga programming language, ay naging hindi sumusuporta lamang sa mga ideyang nakatuon sa bagay, ngunit umuunlad nang naaayon.
Siyempre, kung ang mga naunang recursive algorithm ay mga function lamang na ginamit sa pangkalahatang code ng program, ngayon ang recursion ay maaaring maging bahagi ng mga katangian ng isang object (class), na nagbigay ng mga kawili-wiling pagkakataon sa konteksto ng mana.
Tampok ng modernong OOP
Ang pagbuo ng OOP sa una ay nagpahayag ng mga bagay (mga klase) bilang mga koleksyon ng data at mga katangian (mga pamamaraan). Sa katunayan, ito ay tungkol sa data na may syntax at kahulugan. Ngunit hindi posible na ipakita ang OOP bilang isang tool para sa pamamahala ng mga tunay na bagay.
Ang OOP ay naging isang tool para sa pamamahala ng mga bagay na "computer nature". Ang isang script, isang button, isang menu item, isang menu bar, isang tag sa isang browser window ay isang bagay. Ngunit hindi isang makina, isang produktong pagkain, isang salita, o isang pangungusap. Ang mga tunay na bagay ay nanatili sa labas ng object-oriented programming, at ang mga tool sa computer ay nagkaroon ng bagong pagkakatawang-tao.
Dahil sa mga pagkakaiba sa mga sikat na programming language, maraming dialect ng OOP ang lumitaw. Sa mga tuntunin ng semantika, halos katumbas ang mga ito, at ang kanilang pagtuon sa instrumental na globo, at hindi sa inilapat, ay ginagawang posible na kunin ang paglalarawan ng mga tunay na bagay sa kabila.algorithm at tiyakin ang kanilang cross-platform at cross-language na "existence".
Mga stack at function na mekanismo ng tawag
Ang mga mekanismo para sa mga function ng pagtawag (procedure, algorithm) ay nangangailangan ng pagpasa ng data (parameter), pagbabalik ng resulta, at pag-alala sa address ng operator na dapat makatanggap ng kontrol pagkatapos makumpleto ang function (procedure).
Karaniwan, ang stack ay ginagamit para sa layuning ito, bagama't ang mga programming language o ang developer mismo ay maaaring magbigay ng iba't ibang opsyon para sa paglilipat ng kontrol. Ang modernong programming ay umamin na ang pangalan ng isang function ay maaaring hindi lamang isang parameter: maaari itong mabuo sa panahon ng pagpapatupad ng algorithm. Maaari ding gumawa ng algorithm habang nagsasagawa ng isa pang algorithm.
Ang konsepto ng recursive algorithm, kapag ang kanilang mga pangalan at katawan ay maaaring matukoy sa oras ng pagbuo ng gawain (pagpili ng nais na algorithm), nagpapalawak ng recursiveness hindi lamang sa kung paano gawin ang isang bagay, kundi pati na rin kung sino ang eksaktong dapat gawin mo. Ang pagpili ng algorithm sa pamamagitan ng "makabuluhang" pangalan nito ay nangangako, ngunit nagdudulot ng mga paghihirap.
Recursiveness sa isang set ng mga function
Hindi mo masasabi na ang isang algorithm ay recursive kapag tinawag nito ang sarili nito at iyon na. Ang programming ay hindi isang dogma, at ang konsepto ng recursiveness ay hindi isang eksklusibong kinakailangan upang tawagan ang iyong sarili mula sa katawan ng iyong sariling algorithm.
Ang mga praktikal na aplikasyon ay hindi palaging nagbibigay ng malinis na solusyon. Kadalasan, ang paunang data ay dapat ihanda, at ang resulta ng recursive na tawag ay dapat na masuri sa konteksto ng buong problema (ang buong algorithm) sapangkalahatan.
Sa katunayan, hindi lamang bago tawagin ang isang recursive function, ngunit pagkatapos din itong makumpleto, isa pang program ang maaari o dapat na tawagan. Kung walang mga espesyal na problema sa tawag: ang recursive function na A() ay tumatawag sa function B(), na gumagawa ng isang bagay at tumatawag sa A(), pagkatapos ay may problema kaagad sa pagbabalik ng kontrol. Matapos makumpleto ang recursive na tawag, ang function A() ay dapat makatanggap ng kontrol upang muling tawagan ang B(), na tatawag dito muli. Ang pagbabalik ng kontrol ayon sa nararapat sa pagkakasunud-sunod sa stack pabalik sa B() ay ang maling solusyon.
Ang programmer ay hindi limitado sa pagpili ng mga parameter at maaaring kumpletuhin ang mga ito gamit ang mga pangalan ng function. Sa madaling salita, ang perpektong solusyon ay ipasa ang pangalan ng B() sa A() at hayaan ang A() mismo na tumawag sa B(). Sa kasong ito, walang magiging problema sa pagbabalik ng kontrol, at ang pagpapatupad ng recursive algorithm ay magiging mas transparent.
Pag-unawa at antas ng recursion
Ang problema sa pagbuo ng mga recursive algorithm ay kailangan mong maunawaan ang dynamics ng proseso. Kapag gumagamit ng recursion sa mga object method, lalo na sa antas ng abstract ancestor, may problema sa pag-unawa sa sarili mong algorithm sa konteksto ng oras ng pagpapatupad nito.
Sa kasalukuyan, walang mga paghihigpit sa antas ng nesting ng mga function at kapasidad ng stack sa mga mekanismo ng tawag, ngunit may problema sa pag-unawa: sa anong oras kung aling antas ng data o kung aling lugar sa pangkalahatang algorithm na tinatawag na recursive function at kung anong bilang ng mga tawag sa kanyang sarili.
Ang mga kasalukuyang tool sa pag-debug ay kadalasang walang kapangyarihansabihin sa programmer ang tamang solusyon.
Mga loop at recursion
Itinuturing na ang cyclic execution ay katumbas ng recursion. Sa katunayan, sa ilang mga kaso, maaaring ipatupad ang recursive algorithm sa syntax ng conditional at cyclic construct.
Gayunpaman, kung may malinaw na pag-unawa na ang isang partikular na function ay dapat ipatupad sa pamamagitan ng recursive algorithm, ang anumang panlabas na paggamit ng loop o conditional na mga pahayag ay dapat iwanan.
Ang ibig sabihin dito ay ang isang recursive na solusyon sa anyo ng isang function na gumagamit ng sarili nito ay magiging isang kumpletong, functionally complete algorithm. Ang algorithm na ito ay mangangailangan sa programmer na gawin ito nang may pagsisikap, na maunawaan ang dinamika ng algorithm, ngunit ito ang magiging pangwakas na solusyon na hindi nangangailangan ng panlabas na kontrol.
Anumang kumbinasyon ng mga panlabas na conditional at cyclic operator ay hindi magbibigay-daan sa amin na katawanin ang recursive algorithm bilang isang kumpletong function.
Recursion Consensus at OOP
Sa halos lahat ng variant ng pagbubuo ng recursive algorithm, may planong bumuo ng dalawang algorithm. Ang unang algorithm ay bumubuo ng isang listahan ng mga bagay sa hinaharap (mga pagkakataon), at ang pangalawang algorithm ay talagang isang recursive function.
Ang pinakamagandang solusyon ay ang isaayos ang recursion bilang iisang property (paraan) na aktwal na naglalaman ng recursive algorithm, at ilagay ang lahat ng paghahanda sa object constructor.
Ang isang recursive algorithm ay magiging tamang solusyon lamang kapag ito ay gumaganalamang sa kanyang sarili, nang walang panlabas na kontrol at pamamahala. Ang isang panlabas na algorithm ay maaari lamang magbigay ng isang senyas upang gumana. Ang resulta ng gawaing ito ay dapat na ang inaasahang solusyon, nang walang panlabas na suporta.
Ang recursion ay dapat palaging isang kumpletong stand-alone na solusyon.
Intuitive na pag-unawa at functional completeness
Kapag naging de facto na pamantayan ang object-oriented programming, naging malinaw na para makapag-code nang epektibo, kailangan mong baguhin ang sarili mong pag-iisip. Dapat lumipat ang programmer mula sa syntax at semantics ng wika patungo sa dynamics ng semantics sa panahon ng pagpapatupad ng algorithm.
Katangian ng recursion: maaari itong ilapat sa lahat:
- web scraping;
- mga operasyon sa paghahanap;
- pag-parse ng impormasyon sa text;
- pagbabasa o paggawa ng mga dokumento sa MS Word;
- sampling o pagsusuri ng mga tag…
Katangian ng OOP: ginagawang posible na ilarawan ang isang recursive algorithm sa antas ng abstract ancestor, ngunit nagbibigay ito para tumukoy sa mga natatanging inapo, na bawat isa ay may sariling palette ng data at mga katangian.
Ang recursion ay mainam dahil nangangailangan ito ng functional completeness ng algorithm nito. Pinapabuti ng OOP ang pagganap ng isang recursive algorithm sa pamamagitan ng pagbibigay dito ng access sa lahat ng natatanging bata.