Rekursiv algoritme: beskrivelse, analyse, funksjoner og eksempler

Innholdsfortegnelse:

Rekursiv algoritme: beskrivelse, analyse, funksjoner og eksempler
Rekursiv algoritme: beskrivelse, analyse, funksjoner og eksempler
Anonim

Moderne forståelse av rekursjon: definisjon av funksjonalitet og tilgang til den utenfra og fra denne funksjonaliteten. Det antas at rekursjon ble født av matematikere: faktorberegning, uendelige serier, fraktaler, fortsatte brøker … Imidlertid kan rekursjon finnes over alt. Objektive naturlover "betrakter" rekursjon som deres hovedalgoritme og uttrykksform (eksistens), ikke så mye av objektene i den materielle verden, men generelt som hovedalgoritmen for bevegelse.

rekursiv algoritme
rekursiv algoritme

Folk med ulike spesialiteter innen ulike felt innen vitenskap og teknologi bruker den rekursive algoritmen f (x), hvor "x ~/=f (x)". En funksjon som kaller seg selv er en sterk løsning, men å forme og forstå denne løsningen er i de fleste tilfeller en svært vanskelig oppgave.

I gamle tider ble rekursjon brukt for å øke palassplassen. Gjennom et system av speil rettet mot hverandre, kan du skape fantastiske tredimensjonale romlige effekter. Men er det så lett å forstå hvordanjustere disse speilene? Det er enda vanskeligere å bestemme hvor et punkt i rommet er, reflektert gjennom flere speil.

Rekursjon, rekursive algoritmer: mening og syntaks

Problemet, som er formulert ved å gjenta en sekvens av operasjoner, kan løses rekursivt. En enkel algoritme (beregning av en kvadratisk ligning, et skript for å fylle ut en nettside med informasjon, lese en fil, sende en melding…) krever ikke rekursjon.

Hovedforskjellene i algoritmen som tillater en rekursiv løsning:

  • det er en algoritme som må kjøres flere ganger;
  • algoritmen trenger data som endres hver gang;
  • algoritmen trenger ikke å endres hver gang;
  • det er en siste betingelse: Algoritmen er rekursiv - ikke uendelig.

Generelt kan det ikke hevdes at engangsutførelse er en nødvendig betingelse for fravær av rekursjonsgrunn. Du kan heller ikke kreve en obligatorisk sluttbetingelse: uendelige rekursjoner har sitt eget omfang.

Algoritmen er rekursiv: når en sekvens av operasjoner utføres gjentatte ganger, på data som endres hver gang og gir et nytt resultat hver gang.

Rekursjonsformel

Den matematiske forståelsen av rekursjon og dens analoge i programmering er annerledes. Matematikk, selv om det er tegn på programmering, men programmering er matematikk av mye høyere orden.

rekursiv algoritme f
rekursiv algoritme f

En velskrevet algoritme er som et speil av forfatterens intellekt. Generellrekursjonsformelen i programmering er "f(x)", der "x ~/=f(x)" har minst to tolkninger. Her er "~" likheten eller fraværet av resultatet, og "=" er tilstedeværelsen av resultatet av funksjonen.

Første alternativ: datadynamikk.

  • funksjonen "f(x)" har en rekursiv og uforanderlig algoritme;
  • "x" og resultatet "f(x)" har nye verdier hver gang, resultatet "f(x)" er den nye "x"-parameteren til denne funksjonen.

Andre alternativ: kodedynamikk.

  • funksjonen "f(x)" har flere algoritmer som avgrenser (analyserer) dataene;
  • dataanalyse - en del av koden og implementering av rekursive algoritmer som utfører ønsket handling - den andre delen av koden;
  • resultatet av funksjonen "f(x)" er ikke.

Ingen resultat er norm alt. Programmering er ikke matematikk, her trenger ikke resultatet være eksplisitt tilstede. En rekursiv funksjon kan ganske enkelt analysere nettsteder og fylle ut databasen, eller instansiere objekter i henhold til innkommende input.

Data og rekursjon

Programmering av rekursive algoritmer handler ikke om å beregne en faktorial, der funksjonen mottar hver gang en gitt verdi som er én mer eller mindre enn én – implementerings alternativet avhenger av utviklerens preferanse.

Det spiller ingen rolle hvordan den faktorielle "8!"algoritme som strengt følger denne formelen.

Behandling av informasjon er "matematikk" av en helt annen rekkefølge. Rekursive funksjoner og algoritmer her opererer på bokstaver, ord, setninger, setninger og avsnitt. Hvert neste nivå bruker det forrige.

Inndatastrømmen analyseres over et bredt spekter av forhold, men analyseprosessen er generelt rekursiv. Det gir ingen mening å skrive unike algoritmer for alle varianter av inngangsstrømmen. Det bør være én funksjonalitet. Her er rekursive algoritmer eksempler på hvordan man kan danne en utdatastrøm som er tilstrekkelig til inngangen. Dette er ikke resultatet av den rekursive algoritmen, men det er den ønskede og nødvendige løsningen.

abstraksjon, rekursjon og OOP

Objektorientert programmering (OOP) og rekursjon er fundament alt forskjellige enheter, men de utfyller hverandre perfekt. Abstraksjon har ingenting med rekursjon å gjøre, men gjennom linsen til OOP skaper den muligheten for å implementere kontekstuell rekursjon.

For eksempel blir informasjon analysert, og bokstaver, ord, setninger, setninger og avsnitt utheves separat. Utvikleren vil selvsagt sørge for å lage forekomster av objekter av disse fem typene og tilby en løsning med rekursive algoritmer på hvert nivå.

programmering av rekursive algoritmer
programmering av rekursive algoritmer

I mellomtiden, hvis på bokstavnivået "det er ingen vits i å lete etter mening", så vises semantikk på ordnivå. Du kan dele ord inn i verb, substantiv, adverb, preposisjoner… Du kan gå videre og definere kasus.

På frasenivå er semantikk supplert med skilletegn og logikkordkombinasjoner. På setningsnivå finner man et mer perfekt nivå av semantikk, og et avsnitt kan betraktes som en fullstendig tanke.

Objektorientert utvikling forutbestemmer arven til egenskaper og metoder og foreslår å starte hierarkiet av objekter med å skape en fullstendig abstrakt stamfar. Samtidig, uten tvil, vil analysen av hver etterkommer være rekursiv og vil ikke avvike for mye på teknisk nivå i mange posisjoner (bokstaver, ord, setninger og setninger). Avsnitt, som fullstendige tanker, kan skille seg ut fra denne listen, men de er ikke essensen.

Det er viktig at den overveldende delen av algoritmen kan formuleres på abstrakt forfedrenivå, og foredle den på nivået til hver etterkommer med data og metoder k alt fra abstrakt nivå. I denne sammenhengen åpner abstraksjon nye horisonter for rekursjon.

Historiske trekk ved OOP

OOP har kommet til programvareverdenen to ganger, selv om noen eksperter kanskje trekker frem fremveksten av cloud computing og moderne ideer om objekter og klasser som en ny runde i utviklingen av IT-teknologier.

Begrepene "objekt" og "objektiv" i den moderne konteksten til OOP tilskrives vanligvis 50- og 60-tallet av forrige århundre, men de er assosiert med 1965 og fremveksten av Simula, Lisp, Algol, Smalltalk.

På den tiden var ikke programmering spesielt utviklet og kunne ikke svare tilstrekkelig på revolusjonerende konsepter. Kampen mellom ideer og programmeringsstiler (C / C ++ og Pascal - stort sett) var fortsatt langt unna, og databaser ble fortsatt konseptuelt dannet.

rekursjon rekursive algoritmer
rekursjon rekursive algoritmer

På slutten av 80- og begynnelsen av 90-tallet dukket det opp objekter i Pascal og alle husket klasser i C / C ++ - dette markerte en ny runde med interesse for OOP og det var da verktøy, først og fremst programmeringsspråk, ikke ble støtter kun objektorienterte ideer, men utvikler seg deretter.

Selvfølgelig, hvis tidligere rekursive algoritmer bare var funksjoner brukt i den generelle koden til programmet, kunne nå rekursjon bli en del av egenskapene til et objekt (klasse), noe som ga interessante muligheter i sammenheng med arv.

Funksjon av moderne OOP

Utviklingen av OOP erklærte opprinnelig objekter (klasser) som samlinger av data og egenskaper (metoder). Faktisk handlet det om data som har syntaks og mening. Men da var det ikke mulig å presentere OOP som et verktøy for å administrere virkelige objekter.

rekursive funksjoner og algoritmer
rekursive funksjoner og algoritmer

OOP har blitt et verktøy for å håndtere "datamaskinnatur"-objekter. Et skript, en knapp, et menyelement, en menylinje, en kode i et nettleservindu er et objekt. Men ikke en maskin, et matprodukt, et ord eller en setning. Virkelige objekter har holdt seg utenfor objektorientert programmering, og dataverktøy har fått en ny inkarnasjon.

På grunn av forskjellene i populære programmeringsspråk, har mange dialekter av OOP dukket opp. Når det gjelder semantikk, er de praktisk t alt likeverdige, og deres fokus på den instrumentelle sfæren, og ikke på den anvendte, gjør det mulig å ta beskrivelsen av virkelige objekter utoveralgoritmer og sikre deres "eksistens" på tvers av plattformer og på tvers av språk.

Stabler og funksjonsanropsmekanismer

Mekanismer for å kalle opp funksjoner (prosedyrer, algoritmer) krever overføring av data (parametere), returnering av et resultat og husk adressen til operatøren som må motta kontroll etter at funksjonen (prosedyren) er fullført.

eksempler på rekursive algoritmer
eksempler på rekursive algoritmer

Vanligvis brukes stabelen til dette formålet, selv om programmeringsspråk eller utvikleren selv kan tilby en rekke alternativer for overføring av kontroll. Moderne programmering innrømmer at navnet på en funksjon ikke bare kan være en parameter: den kan dannes under utførelsen av algoritmen. En algoritme kan også opprettes mens en annen algoritme kjøres.

Konseptet med rekursive algoritmer, når deres navn og kropp kan bestemmes på tidspunktet for dannelsen av oppgaven (velge ønsket algoritme), utvider rekursiviteten ikke bare til hvordan man gjør noe, men også hvem som skal gjør det. Å velge en algoritme med dets "meningsfulle" navn er lovende, men skaper vanskeligheter.

Rekursivitet på et sett med funksjoner

Du kan ikke si at en algoritme er rekursiv når den kaller seg selv og det er det. Programmering er ikke et dogme, og begrepet rekursivitet er ikke et eksklusivt krav for å ringe deg selv fra kroppen til din egen algoritme.

Praktiske applikasjoner gir ikke alltid en ren løsning. Ofte må de første dataene forberedes, og resultatet av det rekursive kallet må analyseres i sammenheng med hele problemet (hele algoritmen) itot alt.

Faktisk, ikke bare før en rekursiv funksjon kalles, men også etter at den er fullført, kan eller bør et annet program kalles. Hvis det ikke er spesielle problemer med kallet: den rekursive funksjonen A() kaller funksjonen B(), som gjør noe og kaller A(), så er det umiddelbart et problem med retur av kontroll. Etter å ha fullført det rekursive kallet, må funksjon A() motta kontroll for å kalle opp B(), som vil kalle den igjen. Å returnere kontrollen slik den skal være i orden på stabelen tilbake til B() er feil løsning.

Programmeren er ikke begrenset i valg av parametere og kan komplettere dem med funksjonsnavn. Med andre ord, den ideelle løsningen er å overføre navnet på B() til A() og la A() selv kalle B(). I dette tilfellet vil det ikke være noen problemer med å returnere kontroll, og implementeringen av den rekursive algoritmen vil være mer gjennomsiktig.

Forståelse og rekursjonsnivå

Problemet med å utvikle rekursive algoritmer er at du må forstå dynamikken i prosessen. Når du bruker rekursjon i objektmetoder, spesielt på nivået til en abstrakt stamfar, er det et problem med å forstå din egen algoritme i sammenheng med dens utførelsestid.

løse rekursive algoritmer
løse rekursive algoritmer

For øyeblikket er det ingen begrensninger på nesting-nivået til funksjoner og stabelkapasitet i anropsmekanismer, men det er et problem med å forstå: på hvilket tidspunkt hvilket datanivå eller hvilket sted i den generelle algoritmen som kalles det rekursive funksjon og på hvilket antall samtaler hun selv er.

Eksisterende feilsøkingsverktøy er ofte maktesløsefortell programmereren den riktige løsningen.

løkker og rekursjon

Det anses at syklisk utførelse tilsvarer rekursjon. Faktisk, i noen tilfeller kan den rekursive algoritmen implementeres i syntaksen til betingede og sykliske konstruksjoner.

Men hvis det er en klar forståelse av at en bestemt funksjon må implementeres gjennom en rekursiv algoritme, bør all ekstern bruk av en loop eller betingede setninger forlates.

implementering av rekursive algoritmer
implementering av rekursive algoritmer

Meningen her er at en rekursiv løsning i form av en funksjon som bruker seg selv vil være en komplett, funksjonelt komplett algoritme. Denne algoritmen vil kreve at programmereren lager den med innsats, og forstår dynamikken i algoritmen, men det vil være den endelige løsningen som ikke krever ekstern kontroll.

Enhver kombinasjon av eksterne betingede og sykliske operatorer vil ikke tillate oss å representere den rekursive algoritmen som en komplett funksjon.

Recursion Consensus og OOP

I nesten alle varianter av å utvikle en rekursiv algoritme, oppstår en plan for å utvikle to algoritmer. Den første algoritmen genererer en liste over fremtidige objekter (forekomster), og den andre algoritmen er faktisk en rekursiv funksjon.

Den beste løsningen vil være å ordne rekursjon som en enkelt egenskap (metode) som faktisk inneholder den rekursive algoritmen, og legge alt forarbeidet inn i objektkonstruktøren.

En rekursiv algoritme vil bare være den riktige løsningen når den fungererbare av seg selv, uten ekstern kontroll og styring. En ekstern algoritme kan bare gi et signal om å fungere. Resultatet av dette arbeidet bør være den forventede løsningen, uten ekstern støtte.

Rekursjon skal alltid være en fullstendig frittstående løsning.

Intuitiv forståelse og funksjonell fullstendighet

Da objektorientert programmering ble de facto-standarden, ble det åpenbart at for å kode effektivt, må du endre din egen tenkning. Programmereren må gå fra syntaksen og semantikken til språket til dynamikken i semantikken under utførelsen av algoritmen.

Karakteristisk for rekursjon: den kan brukes på alt:

  • nettskraping;
  • søkeoperasjoner;
  • parsing tekstinformasjon;
  • lese eller lage MS Word-dokumenter;
  • prøvetaking eller analyse av tagger…

Karakteristisk for OOP: den gjør det mulig å beskrive en rekursiv algoritme på nivået til en abstrakt stamfar, men sørge for at den refererer til unike etterkommere, som hver har sin egen palett med data og egenskaper.

konseptet med rekursive algoritmer
konseptet med rekursive algoritmer

Rekursjon er ideell fordi den krever funksjonell fullstendighet av algoritmen. OOP forbedrer ytelsen til en rekursiv algoritme ved å gi den tilgang til alle unike barn.

Anbefalt: