Moderni ymmärtäminen rekursiosta: toiminnallisuuden määrittely ja pääsy siihen ulkopuolelta ja tästä toiminnallisuudesta. Uskotaan, että rekursio on matemaatikoiden synnyttämä: tekijälaskenta, äärettömät sarjat, fraktaalit, jatkuvat murtoluvut… Rekursiota löytyy kuitenkin kaikki alta. Objektiiviset luonnonlait "pitävät" rekursiota pääalgoritminaan ja ilmaisumuotonaan (olemassaolo) ei niinkään aineellisen maailman kohteina, vaan yleensä liikkeen pääalgoritmina.
Eri tieteen ja tekniikan aloilla työskentelevät ihmiset käyttävät rekursiivista algoritmia f (x), jossa "x ~/=f (x)". Itseään kutsuva funktio on vahva ratkaisu, mutta tämän ratkaisun muodostaminen ja ymmärtäminen on useimmissa tapauksissa erittäin vaikea tehtävä.
Muinaisina aikoina rekursiota käytettiin lisäämään palatsin tilaa. Toisiaan kohti suunnattujen peilien avulla voit luoda upeita kolmiulotteisia tilatehosteita. Mutta onko se niin helppo ymmärtää mitensäädä nämä peilit? On vielä vaikeampaa määrittää, missä avaruuden piste sijaitsee useiden peilien läpi heijastuneena.
Rekursio, rekursiiviset algoritmit: merkitys ja syntaksi
Ongelma, joka muotoillaan toistamalla operaatiosarja, voidaan ratkaista rekursiivisesti. Yksinkertainen algoritmi (neliöyhtälön laskeminen, skripti verkkosivun täyttämiseksi tiedoilla, tiedoston lukeminen, viestin lähettäminen…) ei vaadi rekursiota.
Rekursiivisen ratkaisun mahdollistavan algoritmin tärkeimmät erot:
- on algoritmi, joka on suoritettava useita kertoja;
- algoritmi tarvitsee tietoja, jotka muuttuvat joka kerta;
- algoritmin ei tarvitse muuttua joka kerta;
- on viimeinen ehto: algoritmi on rekursiivinen – ei ääretön.
Yleensä ei voida väittää, että kertaluonteinen suoritus olisi välttämätön edellytys sille, ettei rekursiolle ole syytä. Et myöskään voi vaatia pakollista loppuehtoa: äärettömillä rekursioilla on oma laajuutensa.
Algoritmi on rekursiivinen: kun operaatiosarja suoritetaan toistuvasti, datalle, joka muuttuu joka kerta ja antaa joka kerta uuden tuloksen.
Rekursiokaava
Rekursion ja sen analogin matemaattinen ymmärrys ohjelmoinnissa on erilainen. Matematiikka, vaikka ohjelmoinnin merkkejä onkin, mutta ohjelmointi on paljon korkeampaa matematiikkaa.
Hyvin kirjoitettu algoritmi on kuin tekijänsä älyn peili. Kenraaliohjelmoinnin rekursiokaava on "f(x)", missä "x ~/=f(x)" on vähintään kaksi tulkintaa. Tässä "~" on tuloksen samank altaisuus tai puuttuminen, ja "=" on funktion tuloksen läsnäolo.
Ensimmäinen vaihtoehto: datadynamiikka.
- funktiolla "f(x)" on rekursiivinen ja muuttumaton algoritmi;
- "x" ja tuloksella "f(x)" on joka kerta uudet arvot, tulos "f(x)" on tämän funktion uusi "x"-parametri.
Toinen vaihtoehto: koodidynamiikka.
- funktiolla "f(x)" on useita algoritmeja, jotka tarkentavat (analysoivat) tietoja;
- dataanalyysi - yksi osa koodista ja halutun toiminnon suorittavien rekursiivisten algoritmien toteutus - koodin toinen osa;
- funktion "f(x)" tulos ei ole.
Mikään tulos ei ole normaali. Ohjelmointi ei ole matematiikkaa, tässä tuloksen ei tarvitse olla eksplisiittisesti läsnä. Rekursiivinen funktio voi yksinkertaisesti jäsentää sivustoja ja täyttää tietokannan tai luoda objekteja saapuvan syötteen mukaan.
Data ja rekursio
Rekursiivisten algoritmien ohjelmointi ei tarkoita kertoimen laskemista, jossa funktio saa joka kerta tietyn arvon, joka on yksi enemmän tai vähemmän kuin yksi - toteutusvaihtoehto riippuu kehittäjän mieltymyksistä.
Sillä ei ole väliä, kuinka faktoriaalinen "8!"algoritmi, joka noudattaa tarkasti tätä kaavaa.
Tiedon käsittely on "matematiikkaa" aivan eri järjestyksessä. Rekursiiviset funktiot ja algoritmit toimivat tässä kirjaimilla, sanoilla, lauseilla, lauseilla ja kappaleilla. Jokainen seuraava taso käyttää edellistä.
Syötetietovirta analysoidaan useissa olosuhteissa, mutta analyysiprosessi on yleensä rekursiivinen. Ei ole mitään järkeä kirjoittaa ainutlaatuisia algoritmeja kaikille syöttövirran muunnelmille. Yksi toiminto pitäisi olla. Tässä rekursiiviset algoritmit ovat esimerkkejä siitä, kuinka muodostaa tulovirta, joka on riittävä tulolle. Tämä ei ole rekursiivisen algoritmin tulos, mutta se on haluttu ja tarpeellinen ratkaisu.
Abstraktio, rekursio ja OOP
Object-oriented ohjelmointi (OOP) ja rekursio ovat pohjimmiltaan erilaisia kokonaisuuksia, mutta ne täydentävät toisiaan täydellisesti. Abstraktiolla ei ole mitään tekemistä rekursion kanssa, mutta OOP:n linssin kautta se luo mahdollisuuden kontekstuaalisen rekursion toteuttamiseen.
Esimerkiksi tietoja jäsennetään ja kirjaimet, sanat, lauseet, lauseet ja kappaleet korostetaan erikseen. Ilmeisesti kehittäjä huolehtii näiden viiden tyyppisten objektien esiintymien luomisesta ja tarjoaa ratkaisun rekursiivisiin algoritmeihin kullakin tasolla.
Sillä välin, jos kirjainten tasolla "merkitystä ei kannata etsiä", niin semantiikka näkyy sanojen tasolla. Voit jakaa sanat verbeiksi, substantiiviksi, adverbeiksi, prepositioihin… Voit mennä pidemmälle ja määritellä tapauksia.
Fraasitasolla semantiikkaa täydennetään välimerkeillä ja logiikallasanayhdistelmiä. Lausetasolta löytyy täydellisempi semantiikan taso, ja kappaletta voidaan pitää täydellisenä ajatuksena.
Objektisuuntautunut kehitys määrittelee ominaisuuksien ja menetelmien periytymisen ja ehdottaa objektien hierarkian aloittamista täysin abstraktin esivanhemman luomisella. Samanaikaisesti jokaisen jälkeläisen analyysi on epäilemättä rekursiivinen eikä eroa teknisellä tasolla liikaa monissa kohdissa (kirjaimet, sanat, lauseet ja lauseet). Kappaleet, kuten täydelliset ajatukset, voivat erottua tästä luettelosta, mutta ne eivät ole ydin.
On tärkeää, että suurin osa algoritmista voidaan muotoilla abstraktin esi-isän tasolla ja jalostaa sitä jokaisen jälkeläisen tasolla abstraktilta tasolta kutsutuilla tiedoilla ja menetelmillä. Tässä yhteydessä abstraktio avaa uusia horisontteja rekursiolle.
OOP:n historialliset piirteet
OOP on tullut ohjelmistojen maailmaan kahdesti, vaikka jotkut asiantuntijat saattavat mainita pilvitekniikan ja nykyaikaisten ideoiden syntymisen objekteista ja luokista uutena kierroksena IT-teknologioiden kehityksessä.
Termit "objekti" ja "objekti" liitetään nykyaikaisessa OOP:n kontekstissa yleensä viime vuosisadan 50- ja 60-luvuille, mutta ne liittyvät vuoteen 1965 sekä Simulan, Lispin, Algolin, Smalltalkin syntymiseen..
Noihin aikoihin ohjelmointi ei ollut erityisen kehittynyt, eikä se kyennyt vastaamaan riittävästi vallankumouksellisiin käsitteisiin. Ideoiden ja ohjelmointityylien kamppailu (C / C ++ ja Pascal - enimmäkseen) oli vielä kaukana, ja tietokannat olivat vielä käsitteellisiä.
80-luvun lopulla ja 90-luvun alussa esineitä ilmestyi Pascalissa ja kaikki muistivat C / C ++ -luokat - tämä merkitsi uutta kiinnostusta OOP:iin, ja silloin työkalut, pääasiassa ohjelmointikielet, eivät enää tukevat vain olio-ideoita, mutta kehittyvät sen mukaisesti.
Tietenkin, jos aiemmin rekursiiviset algoritmit olivat vain ohjelman yleisessä koodissa käytettyjä funktioita, nyt rekursiosta voisi tulla osa objektin (luokan) ominaisuuksia, mikä tarjosi mielenkiintoisia mahdollisuuksia periytymisen yhteydessä.
modernin OOP:n ominaisuus
OOP:n kehittäminen alun perin määritellyt objektit (luokat) data- ja ominaisuuskokoelmiksi (menetelmiksi). Itse asiassa kyse oli tiedoista, joilla on syntaksi ja merkitys. Mutta silloin ei ollut mahdollista esittää OOP:ta todellisten objektien hallintatyökaluna.
OOP:sta on tullut työkalu "tietokoneluonteisten" objektien hallintaan. Skripti, painike, valikon kohta, valikkorivi, tunniste selainikkunassa on objekti. Mutta ei kone, ruokatuote, sana tai lause. Todelliset esineet ovat jääneet olio-ohjelmoinnin ulkopuolelle, ja tietokonetyökalut ovat saaneet uuden ilmentymän.
Suosittujen ohjelmointikielten eroista johtuen monia OOP:n murteita on syntynyt. Semantiikassa ne ovat käytännössä samanarvoisia, ja niiden keskittyminen instrumentaaliseen sfääriin, ei sovellettavaan, mahdollistaa todellisten objektien kuvauksen viemisen pidemmälle.algoritmeja ja varmistaa niiden "olemassaolo" eri alustojen ja kielten välillä.
Pinot ja funktiokutsumekanismit
Mekanismit funktioiden kutsumiseksi (menettelyt, algoritmit) edellyttävät tietojen (parametrien) välittämistä, tuloksen palauttamista ja sen operaattorin osoitteen muistamista, jonka on saatava ohjaus funktion (menettelyn) valmistumisen jälkeen.
Yleensä pinoa käytetään tähän tarkoitukseen, vaikka ohjelmointikielet tai itse kehittäjä voivat tarjota erilaisia vaihtoehtoja ohjauksen siirtoon. Nykyaikainen ohjelmointi myöntää, että funktion nimi ei voi olla vain parametri: se voidaan muodostaa algoritmia suoritettaessa. Algoritmi voidaan luoda myös toista algoritmia suoritettaessa.
Rekursiivisten algoritmien käsite, kun niiden nimet ja rungot voidaan määrittää tehtävän muodostushetkellä (halutun algoritmin valinta), laajentaa rekursiivisuuden paitsi siihen, miten jokin tehdään, vaan myös siihen, kenen pitäisi tarkalleen ottaen tee se. Algoritmin valitseminen sen "merkittävän" nimen perusteella on lupaavaa, mutta aiheuttaa vaikeuksia.
Rekursiivisuus funktioissa
Et voi sanoa, että algoritmi on rekursiivinen, kun se kutsuu itseään, ja siinä se. Ohjelmointi ei ole dogmi, eikä rekursiivisuuden käsite ole yksinomainen vaatimus kutsua itseäsi oman algoritmisi rungosta.
Käytännön sovellukset eivät aina anna puhdasta ratkaisua. Usein alkutiedot on valmisteltava ja rekursiivisen kutsun tulos on analysoitava koko ongelman (koko algoritmin) yhteydessä.kaiken kaikkiaan.
Itse asiassa, ei vain ennen rekursiivisen funktion kutsumista, vaan myös sen jälkeen, kun se on valmis, toinen ohjelma voidaan kutsua tai pitäisi kutsua. Jos kutsussa ei ole erityisiä ongelmia: rekursiivinen funktio A() kutsuu funktiota B(), joka tekee jotain ja kutsuu A(), niin heti on ongelma ohjauksen palauttamisessa. Kun rekursiivinen kutsu on suoritettu, funktion A() on saatava ohjaus, jotta se voi kutsua uudelleen B(), joka kutsuu sitä uudelleen. Ohjauksen palauttaminen pinossa järjestyksessä takaisin kohtaan B() on väärä ratkaisu.
Ohjelmoija ei ole rajoitettu parametrien valinnassa ja voi täydentää niitä funktioiden nimillä. Toisin sanoen ihanteellinen ratkaisu on välittää B():n nimi A():lle ja antaa A():n itse kutsua B():tä. Tässä tapauksessa ohjauksen palauttamisessa ei ole ongelmia, ja rekursiivisen algoritmin toteutus on läpinäkyvämpää.
Ymmärrys ja rekursion taso
Rekursiivisten algoritmien kehittämisen ongelma on, että sinun on ymmärrettävä prosessin dynamiikka. Käytettäessä rekursiota objektimetodeissa, erityisesti abstraktin esi-isän tasolla, on ongelmia oman algoritmin ymmärtämisessä sen suoritusajan kontekstissa.
Tällä hetkellä ei ole rajoituksia toimintojen sisäkkäisyystasolle ja pinokapasiteetille puhelumekanismeissa, mutta ongelmana on ymmärrys: millä hetkellä mitä datatasoa tai mitä paikkaa yleisessä algoritmissa kutsutaan rekursiiviseksi. toiminto ja kuinka monta puhelua hän itse soittaa.
Olemassa olevat virheenkorjaustyökalut ovat usein voimattomiakerro ohjelmoijalle oikea ratkaisu.
Silmukat ja rekursio
Jaksottaisen suorituksen katsotaan vastaavan rekursiota. Todellakin, joissain tapauksissa rekursiivinen algoritmi voidaan toteuttaa ehdollisten ja syklisten konstruktien syntaksissa.
Jos kuitenkin ymmärretään selkeästi, että tietty funktio on toteutettava rekursiivisen algoritmin avulla, kaikki silmukan tai ehdollisten lauseiden ulkoinen käyttö tulee luopua.
Tässä tarkoitetaan sitä, että itseään käyttävän funktion muodossa oleva rekursiivinen ratkaisu on täydellinen, toiminnallisesti täydellinen algoritmi. Tämä algoritmi edellyttää, että ohjelmoija luo sen vaivattomasti ja ymmärtää algoritmin dynamiikan, mutta se on lopullinen ratkaisu, joka ei vaadi ulkoista ohjausta.
Mikään ulkoisten ehdollisten ja syklisten operaattoreiden yhdistelmä ei salli meidän esittää rekursiivista algoritmia täydellisenä funktiona.
Recursion Consensus ja OOP
Melkeissä kaikissa rekursiivisen algoritmin kehittämisversioissa syntyy suunnitelma kehittää kaksi algoritmia. Ensimmäinen algoritmi luo listan tulevista objekteista (instanssit), ja toinen algoritmi on itse asiassa rekursiivinen funktio.
Paras ratkaisu olisi järjestää rekursio yhdeksi ominaisuudeksi (menetelmäksi), joka todella sisältää rekursiivisen algoritmin, ja laittaa kaikki valmistelutyöt objektikonstruktoriin.
Rekursiivinen algoritmi on oikea ratkaisu vain, kun se toimiivain itse, ilman ulkoista valvontaa ja hallintaa. Ulkoinen algoritmi voi vain antaa signaalin toiminnalle. Tämän työn tuloksena pitäisi olla odotettu ratkaisu ilman ulkopuolista tukea.
Rekursion tulee aina olla täydellinen itsenäinen ratkaisu.
Intuitiivinen ymmärrys ja toiminnallinen täydellisyys
Kun olio-ohjelmoinnista tuli de facto standardi, kävi selväksi, että koodataksesi tehokkaasti, sinun on muutettava omaa ajatteluasi. Ohjelmoijan on siirryttävä kielen syntaksista ja semantiikasta semantiikan dynamiikkaan algoritmin suorittamisen aikana.
Rekursiolle ominaista: sitä voidaan soveltaa kaikkeen:
- verkon kaapiminen;
- hakutoiminnot;
- tekstitietojen jäsentäminen;
- MS Word -asiakirjojen lukeminen tai luominen;
- tunnisteiden otanta tai analysointi…
OOP:lle ominaista: se mahdollistaa rekursiivisen algoritmin kuvaamisen abstraktin esi-isän tasolla, mutta sen tulee viitata ainutlaatuisiin jälkeläisiin, joilla jokaisella on oma tieto- ja ominaisuuspalettinsa.
Rekursio on ihanteellinen, koska se edellyttää algoritminsa toiminnallista täydellisyyttä. OOP parantaa rekursiivisen algoritmin suorituskykyä antamalla sille pääsyn kaikille ainutlaatuisille lapsille.