Recursief algoritme: beschrijving, analyse, functies en voorbeelden

Inhoudsopgave:

Recursief algoritme: beschrijving, analyse, functies en voorbeelden
Recursief algoritme: beschrijving, analyse, functies en voorbeelden
Anonim

Modern begrip van recursie: definitie van functionaliteit en toegang ertoe van buitenaf en vanuit deze functionaliteit. Er wordt aangenomen dat recursie werd geboren door wiskundigen: factoriële berekening, oneindige reeksen, fractals, kettingbreuken … Recursie is echter overal te vinden. Objectieve natuurwetten "beschouwen" recursie als hun belangrijkste algoritme en vorm van expressie (bestaan), niet zozeer van de objecten van de materiële wereld, maar in het algemeen als het belangrijkste bewegingsalgoritme.

recursief algoritme
recursief algoritme

Mensen met verschillende specialiteiten op verschillende gebieden van wetenschap en technologie gebruiken het recursieve algoritme f (x), waarbij "x ~/=f (x)". Een functie die zichzelf aanroept is een sterke oplossing, maar het vormen en begrijpen van deze oplossing is in de meeste gevallen een zeer moeilijke taak.

In de oudheid werd recursie gebruikt om de paleisruimte te vergroten. Door een systeem van op elkaar gerichte spiegels kun je verbluffende driedimensionale ruimtelijke effecten creëren. Maar is het zo gemakkelijk te begrijpen hoe?deze spiegels afstellen? Het is zelfs nog moeilijker om te bepalen waar een punt in de ruimte is, gereflecteerd door meerdere spiegels.

Recursie, recursieve algoritmen: betekenis en syntaxis

Het probleem, dat wordt geformuleerd door een reeks bewerkingen te herhalen, kan recursief worden opgelost. Een eenvoudig algoritme (een kwadratische vergelijking berekenen, een script om een webpagina met informatie te vullen, een bestand lezen, een bericht verzenden…) vereist geen recursie.

Belangrijkste verschillen van het algoritme dat een recursieve oplossing mogelijk maakt:

  • er is een algoritme dat meerdere keren moet worden uitgevoerd;
  • algoritme heeft gegevens nodig die elke keer veranderen;
  • het algoritme hoeft niet elke keer te veranderen;
  • er is een laatste voorwaarde: het algoritme is recursief - niet oneindig.

Over het algemeen kan niet worden gesteld dat eenmalige uitvoering een noodzakelijke voorwaarde is voor het ontbreken van een reden voor recursie. U kunt ook geen verplichte eindvoorwaarde eisen: oneindige recursies hebben hun eigen reikwijdte.

Het algoritme is recursief: wanneer een reeks bewerkingen herhaaldelijk wordt uitgevoerd, op gegevens die elke keer veranderen en elke keer een nieuw resultaat opleveren.

Recursieformule

Het wiskundige begrip van recursie en zijn analogie in programmeren is anders. Wiskunde, hoewel er tekenen van programmeren zijn, maar programmeren is wiskunde van een veel hogere orde.

recursief algoritme f
recursief algoritme f

Een goed geschreven algoritme is als een spiegel van het intellect van zijn auteur. Algemeende recursieformule in programmeren is "f(x)", waarbij "x ~/=f(x)" minstens twee interpretaties heeft. Hier is "~" de overeenkomst of afwezigheid van het resultaat, en "=" is de aanwezigheid van het resultaat van de functie.

Eerste optie: datadynamica.

  • functie "f(x)" heeft een recursief en onveranderlijk algoritme;
  • "x" en het resultaat "f(x)" hebben elke keer nieuwe waarden, het resultaat "f(x)" is de nieuwe "x" parameter van deze functie.

Tweede optie: code dynamics.

  • functie "f(x)" heeft verschillende algoritmen die de gegevens verfijnen (analyseren);
  • gegevensanalyse - een deel van de code en de implementatie van recursieve algoritmen die de gewenste actie uitvoeren - het tweede deel van de code;
  • het resultaat van de functie "f(x)" is niet.

Geen resultaat is normaal. Programmeren is geen wiskunde, hier hoeft het resultaat niet expliciet aanwezig te zijn. Een recursieve functie kan eenvoudig sites ontleden en de database vullen, of objecten instantiëren volgens de binnenkomende invoer.

Gegevens en recursie

Het programmeren van recursieve algoritmen gaat niet over het berekenen van een faculteit, waarin de functie elke keer een gegeven waarde ontvangt die één meer of minder is dan één - de implementatieoptie hangt af van de voorkeur van de ontwikkelaar.

Het maakt niet uit hoe de faculteit "8!",algoritme dat deze formule strikt volgt.

Het verwerken van informatie is "wiskunde" van een heel andere orde. Recursieve functies en algoritmen werken hier op letters, woorden, zinnen, zinnen en alinea's. Elk volgend niveau gebruikt het vorige.

De invoergegevensstroom wordt geanalyseerd onder een groot aantal omstandigheden, maar het analyseproces is over het algemeen recursief. Het heeft geen zin om voor alle varianten van de invoerstroom unieke algoritmen te schrijven. Er moet één functionaliteit zijn. Hier zijn recursieve algoritmen voorbeelden van hoe een uitvoerstroom kan worden gevormd die geschikt is voor de invoer. Dit is niet de output van het recursieve algoritme, maar het is de gewenste en noodzakelijke oplossing.

Abstractie, recursie en OOP

Objectgeoriënteerd programmeren (OOP) en recursie zijn fundamenteel verschillende entiteiten, maar ze vullen elkaar perfect aan. Abstractie heeft niets te maken met recursie, maar door de lens van OOP creëert het de mogelijkheid om contextuele recursie te implementeren.

Er wordt bijvoorbeeld informatie geparseerd en letters, woorden, zinsdelen, zinnen en alinea's worden afzonderlijk gemarkeerd. Het is duidelijk dat de ontwikkelaar zal zorgen voor het maken van instanties van objecten van deze vijf typen en een oplossing biedt van recursieve algoritmen op elk niveau.

recursieve algoritmen programmeren
recursieve algoritmen programmeren

Ondertussen, als op het niveau van letters "het geen zin heeft om naar betekenis te zoeken", verschijnt semantiek op het niveau van woorden. U kunt woorden verdelen in werkwoorden, zelfstandige naamwoorden, bijwoorden, voorzetsels… U kunt verder gaan en naamvallen definiëren.

Op zinsniveau wordt semantiek aangevuld met leestekens en logicawoordcombinaties. Op het niveau van zinnen wordt een meer perfect niveau van semantiek gevonden, en een alinea kan worden beschouwd als een volledige gedachte.

Objectgeoriënteerde ontwikkeling bepa alt vooraf de overerving van eigenschappen en methoden en stelt voor om de hiërarchie van objecten te starten met het creëren van een volledig abstracte voorouder. Tegelijkertijd zal de analyse van elke afstammeling ongetwijfeld recursief zijn en op technisch niveau in veel posities (letters, woorden, zinnen en zinnen) niet al te veel verschillen. Paragrafen kunnen, net als complete gedachten, opvallen in deze lijst, maar ze zijn niet de essentie.

Het is belangrijk dat het overweldigende deel van het algoritme kan worden geformuleerd op het abstracte voorouderniveau, en het op het niveau van elke afstammeling kan verfijnen met gegevens en methoden die vanaf het abstracte niveau worden aangeroepen. In deze context opent abstractie nieuwe horizonten voor recursie.

Historische kenmerken van OOP

OOP is twee keer in de softwarewereld verschenen, hoewel sommige experts de opkomst van cloudcomputing en moderne ideeën over objecten en klassen als een nieuwe ronde in de ontwikkeling van IT-technologieën beschouwen.

De termen 'object' en 'objectief' in de moderne context van OOP worden meestal toegeschreven aan de jaren 50 en 60 van de vorige eeuw, maar ze worden geassocieerd met 1965 en de opkomst van Simula, Lisp, Algol, Smalltalk.

In die tijd was programmeren niet bijzonder ontwikkeld en kon het niet adequaat reageren op revolutionaire concepten. De strijd van ideeën en programmeerstijlen (C / C ++ en Pascal - meestal) was nog ver weg en databases waren nog steeds conceptueel gevormd.

recursie recursieve algoritmen
recursie recursieve algoritmen

In de late jaren 80 en vroege jaren 90 verschenen er objecten in Pascal en iedereen herinnerde zich klassen in C / C ++ - dit markeerde een nieuwe ronde van interesse in OOP en toen werden tools, voornamelijk programmeertalen, niet meer ondersteunen alleen objectgeoriënteerde ideeën, maar evolueren dienovereenkomstig.

Als eerdere recursieve algoritmen alleen maar functies waren die in de algemene code van het programma werden gebruikt, zou recursie nu onderdeel kunnen worden van de eigenschappen van een object (klasse), wat interessante mogelijkheden bood in de context van overerving.

Kenmerk van moderne OOP

De ontwikkeling van OOP verklaarde aanvankelijk objecten (klassen) als verzamelingen van gegevens en eigenschappen (methoden). In feite ging het om gegevens met syntaxis en betekenis. Maar toen was het niet mogelijk om OOP te presenteren als een hulpmiddel voor het beheren van echte objecten.

recursieve functies en algoritmen
recursieve functies en algoritmen

OOP is een hulpmiddel geworden voor het beheren van "computer-natuur"-objecten. Een script, een knop, een menu-item, een menubalk, een tag in een browservenster is een object. Maar niet een machine, een voedingsproduct, een woord of een zin. Echte objecten zijn buiten objectgeoriënteerd programmeren gebleven en computerhulpmiddelen hebben een nieuwe incarnatie aangenomen.

Vanwege de verschillen in populaire programmeertalen zijn er veel dialecten van OOP ontstaan. In termen van semantiek zijn ze praktisch equivalent, en hun focus op de instrumentele sfeer, en niet op de toegepaste, maakt het mogelijk om de beschrijving van echte objecten verder te brengen danalgoritmen en zorgen voor hun platformonafhankelijke en taaloverschrijdende "bestaan".

Stacks en functie-aanroepmechanismen

Mechanismen voor het aanroepen van functies (procedures, algoritmen) vereisen het doorgeven van gegevens (parameters), het retourneren van een resultaat en het onthouden van het adres van de operator die controle moet krijgen nadat de functie (procedure) is voltooid.

voorbeelden van recursieve algoritmen
voorbeelden van recursieve algoritmen

Meestal wordt de stapel voor dit doel gebruikt, hoewel programmeertalen of de ontwikkelaar zelf een verscheidenheid aan opties kunnen bieden voor het overdragen van controle. Moderne programmering geeft toe dat de naam van een functie niet alleen een parameter kan zijn: hij kan ook worden gevormd tijdens de uitvoering van het algoritme. Een algoritme kan ook worden gemaakt terwijl een ander algoritme wordt uitgevoerd.

Het concept van recursieve algoritmen, wanneer hun namen en lichamen kunnen worden bepaald op het moment van de vorming van de taak (door het gewenste algoritme te kiezen), breidt recursiviteit niet alleen uit naar hoe iets moet worden gedaan, maar ook naar wie dat precies moet doen doe het. Het kiezen van een algoritme met zijn "betekenisvolle" naam is veelbelovend, maar levert moeilijkheden op.

Recursiviteit op een reeks functies

Je kunt niet zeggen dat een algoritme recursief is als het zichzelf aanroept en dat is het dan. Programmeren is geen dogma, en het concept van recursiviteit is geen exclusieve vereiste om jezelf te bellen vanuit het lichaam van je eigen algoritme.

Praktische toepassingen geven niet altijd een schone oplossing. Vaak moeten de initiële gegevens worden voorbereid en moet het resultaat van de recursieve aanroep worden geanalyseerd in de context van het hele probleem (het hele algoritme) inalgemeen.

In feite, niet alleen voordat een recursieve functie wordt aangeroepen, maar ook nadat deze is voltooid, kan of moet een ander programma worden aangeroepen. Als er geen speciale problemen zijn met de aanroep: de recursieve functie A() roept de functie B() aan, die iets doet en A() aanroept, dan is er meteen een probleem met de terugkeer van de controle. Nadat de recursieve aanroep is voltooid, moet functie A() controle krijgen om B() opnieuw aan te roepen, die deze opnieuw zal aanroepen. De controle teruggeven zoals het hoort op de stapel terug naar B() is de verkeerde oplossing.

De programmeur is niet beperkt in de keuze van parameters en kan deze aanvullen met functienamen. Met andere woorden, de ideale oplossing is om de naam van B() door te geven aan A() en A() zelf B(te laten noemen). In dit geval zullen er geen problemen zijn met het teruggeven van controle en zal de implementatie van het recursieve algoritme transparanter zijn.

Begrip en niveau van recursie

Het probleem met het ontwikkelen van recursieve algoritmen is dat je de dynamiek van het proces moet begrijpen. Bij het gebruik van recursie in objectmethoden, vooral op het niveau van een abstracte voorouder, is er een probleem om uw eigen algoritme te begrijpen in de context van zijn uitvoeringstijd.

recursieve algoritmen oplossen
recursieve algoritmen oplossen

Momenteel zijn er geen beperkingen op het nesting-niveau van functies en stapelcapaciteit in oproepmechanismen, maar er is een probleem om te begrijpen: op welk moment in de tijd welk dataniveau of welke plaats in het algemene algoritme recursief wordt genoemd functie en op hoeveel oproepen ze zelf is.

Bestaande tools voor foutopsporing zijn vaak machteloosvertel de programmeur de juiste oplossing.

Lussen en recursie

Er wordt aangenomen dat cyclische uitvoering gelijk is aan recursie. In sommige gevallen kan het recursieve algoritme inderdaad worden geïmplementeerd in de syntaxis van voorwaardelijke en cyclische constructies.

Als er echter een duidelijk begrip is dat een bepaalde functie moet worden geïmplementeerd via een recursief algoritme, moet elk extern gebruik van een lus of voorwaardelijke instructies worden afgeschaft.

implementatie van recursieve algoritmen
implementatie van recursieve algoritmen

De betekenis hier is dat een recursieve oplossing in de vorm van een functie die zichzelf gebruikt een compleet, functioneel compleet algoritme zal zijn. Dit algoritme vereist dat de programmeur het met moeite maakt, waarbij hij de dynamiek van het algoritme begrijpt, maar het zal de uiteindelijke oplossing zijn waarvoor geen externe controle nodig is.

Elke combinatie van externe voorwaardelijke en cyclische operatoren stelt ons niet in staat om het recursieve algoritme weer te geven als een volledige functie.

Recursieconsensus en OOP

In bijna alle varianten van het ontwikkelen van een recursief algoritme ontstaat een plan om twee algoritmen te ontwikkelen. Het eerste algoritme genereert een lijst met toekomstige objecten (instanties) en het tweede algoritme is eigenlijk een recursieve functie.

De beste oplossing zou zijn om recursie te rangschikken als een enkele eigenschap (methode) die daadwerkelijk het recursieve algoritme bevat, en al het voorbereidende werk in de objectconstructor te stoppen.

Een recursief algoritme is alleen de juiste oplossing als het werktalleen door hemzelf, zonder externe controle en beheer. Een extern algoritme kan alleen een signaal geven om te werken. Het resultaat van dit werk zou de verwachte oplossing moeten zijn, zonder externe ondersteuning.

Recursie moet altijd een complete stand-alone oplossing zijn.

Intuïtief begrip en functionele volledigheid

Toen objectgeoriënteerd programmeren de de facto standaard werd, werd het duidelijk dat om effectief te coderen, je je eigen denken moet veranderen. De programmeur moet tijdens de uitvoering van het algoritme overstappen van de syntaxis en semantiek van de taal naar de dynamiek van de semantiek.

Kenmerk van recursie: het kan op alles worden toegepast:

  • webschrapen;
  • zoekbewerkingen;
  • tekstinformatie ontleden;
  • MS Word-documenten lezen of maken;
  • tags bemonsteren of analyseren…

Kenmerk van OOP: het maakt het mogelijk om een recursief algoritme te beschrijven op het niveau van een abstracte voorouder, maar zorgt ervoor dat het verwijst naar unieke nakomelingen, die elk hun eigen palet van gegevens en eigenschappen hebben.

concept van recursieve algoritmen
concept van recursieve algoritmen

Recursie is ideaal omdat het de functionele volledigheid van het algoritme vereist. OOP verbetert de prestaties van een recursief algoritme door het toegang te geven tot alle unieke kinderen.

Aanbevolen: