Ciao.
Questo non voleva Lulu.
E bentornato.
Finora abbiamo esaminato un metodo per lavorare su un altro metodo per realizzare qualcosa.
Ora diamo un'occhiata a un metodo che funziona da solo per ottenere qualcosa di non verificato come ricorsione
che è una tecnica di programmazione interessante e non importante.
Quindi il metodo che nel lavoro stesso viene anche definito un metodo ricorsivo e ci riferiamo a
tale chiamata di invocazione come una chiamata ricorsiva.
Quindi, quando un metodo si richiama, significa essenzialmente che il metodo è in esecuzione di nuovo.
E durante quella fase di reintroduzione, potrebbe fare un'altra volta una chiamata ricorsiva su Saddam il
terzo mondo.
Quindi questo processo di rielaborazione del metodo eseguito di nuovo può accadere per un certo numero di
volte fino a quando una condizione viene soddisfatta in una delle esecuzioni.
Una delle esecuzioni del metodo sotto quella ricorsione si fermerebbe e con tale ricorsione ciò che otteniamo
è un core compatto ed elegante che è un codice molto facile da capire.
Non solo alcuni tipi di problemi possono essere implementati usando la ricorsione e questi tipi
di problemi possono anche essere implementati usando un loop non ricorsivo molto simile, anche se non sono lontani.
Questo perché con la ricorsione abbiamo lo script per fare invocazione del metodo in modo che la
ripetitività possa anche essere simulata usando cicli come la forma d'arte.
Ma quando implementato in modo non ricorsivo, ciò che otteniamo è un complesso chiamato.
Quindi ciò che la ricorsione ci sta comprando è chiaramente espresso e vedremo che questo mi ha scioccato in una demo.
Ora sappiamo che una chiamata al metodo risolverà qualche problema ma che la ricorsione quando un metodo invoca se
stessa sarebbe indirizzare un sottotema che è un problema rimarrebbe lo stesso.
Ma i dati di input per quella particolare istanza di esecuzione del metodo sarebbero in genere in sottoinsiemi più piccoli.
Quindi con ogni invocazione ricorsiva il problema diventa sempre più piccolo finché non può essere reso più
piccolo.
A quel punto vediamo che abbiamo raggiunto un biscotto.
Quindi questa è la condizione che soddisferebbe in una delle invocazioni del metodo.
Questo è quello che menzionavo prima.
Quindi, quando il caso migliore viene raggiunto, le interruzioni di ricorsione su fattoriali sono un tipico esempio che viene utilizzato quando si introduce
la ricorsione.
Qui abbiamo quattro fattoriali che sappiamo essere quattro volte tre volte due volte uno.
E più generalmente avremmo questo quattro fattoriale sarebbe N volte e meno una volta e meno due e
così via fino ad arrivare a 1 e questo può essere esposto noi e tempi e meno 1 fattoriale come puoi vedere
abbiamo una rappresentazione ricorsiva ecco che quando n viene sostituito con N meno uno avremmo ottenuto e meno
una volta e meno due fattoriali e dopo di essa e meno due fattoriali otterremmo e
meno due volte e meno tre fattoriali e questo continuerebbe fino a quando non arriveremo a 1 volte 0 fattoriale.
Ora andiamo avanti e implementiamo questa funzionalità fattoriale utilizzando la ricorsione per questa
demo.
Una nuova classe chiamata ricorsione è stata creata all'interno della directory di base in modo da poter andare avanti e
creare questa classe chiamata ricorsione all'interno della directory di base per questa demo.
Lo mostrerò nel mio Eclipse Ed, quindi eseguirò questo programma da dentro eclipse.
E se stai usando il normale tutor extra puoi compilarlo ed eseguirlo dal problema del comando.
Quindi implementeremo fattoriali usando sia l'approccio non ricorsivo sia quello ricorsivo.
In questo modo possiamo vedere come il codice sembra più leggibile utilizzando l'approccio ricorsivo.
Quindi per entrambi abbiamo due metodi diversi.
Per prima cosa esaminiamo l'approccio non ricorsivo e il metodo è stato chiamato come fattoriale e dove R
sta per Non ricorsivo.
E il metodo è implementato.
Quindi ci limiteremo a guardarlo.
Ma in seguito implementeremo l'approccio ricorsivo usando questo metodo chiamato fattoriale ora.
Qui l'input è e il che significa che dobbiamo calcolare un fattoriale.
Quindi questo approccio non ricorsivo usa un ciclo while per implementarlo qui.
La prima cosa che stiamo facendo è controllare che l'input n sia 0 o 1.
Se è 0 o 1, restituiremo il valore 1 perché 0 fattoriale o 1 fattoriale è 1.
Ora se è qualcosa di diverso da quello.
Va bene allora questa condizione fallirebbe.
Ora l'assunto è che passeremo solo un valore positivo.
Va bene quindi il valore deve essere zero o maggiore di zero per essere negativo.
Quindi se è qualcosa di diverso da zero su uno allora lo siamo.
Intendo qui e stiamo assegnando e a questa variabile temporanea chiamata fattoriale e il fattoriale questo calcolato
qui.
Quindi stiamo usando un ciclo while e la condizione è e maggiore o uguale a 2.
E facciamo questa iterazione e ogni iterazione stiamo anche discriminando.
E così lo facciamo fino e il più ricco 2.
Va bene.
Ed è per questo che lavoreremo, lo itereremo fino a quando diventerà 2 e in ogni iterazione stiamo calcolando il
fattoriale qui.
Stai dicendo tempi fattoriali e meno 1.
Quindi è così che factorial sarà computer.
Quindi se lo è, sarebbe quattro volte tre volte due volte uno.
Destra.
Quindi inizialmente facciamo solo un esempio e guardiamolo.
Quindi, assumiamo che il valore passato sia 4.
Va bene quindi dobbiamo calcolare per factorial con un 24.
Ecco.
E sarebbero quattro così fattoriali sarebbero quattro qui e all'interno del ciclo qui.
Perché la condizione è vera per maggiore o uguale a 2.
Quindi questo sarebbe quattro volte e meno uno.
Quindi sarebbe quattro volte tre che è uguale a.
E stiamo discriminando.
E 2 3.
Quindi il prossimo nella successiva iterazione 3 sarebbe maggiore o uguale a 2.
Va bene.
Che è vero.
E qui anche l'attuale valore di factorial.
Quindi ora sarebbe dodici volte tre meno 1 che è 2.
E qui.
E sarebbe dannoso per 2.
E questo sarebbe 24 qui.
Quindi fattoriale è venti per il valore corrente di fattoriale e 2 è maggiore o uguale a due che
è anche vero.
Quindi nella prossima iterazione sarebbe 24 volte 2 meno 1 che è 1.
Quindi questo sarebbe 24 e diventerebbe 1 dopo che la condizione fallirebbe e avremmo accettato il ciclo e
avremmo restituito il valore corrente di fattoriale con solo 24, quindi è fattoriale un'ora.
Ora diamo un'occhiata alla versione ricorsiva in modo che sappiamo che deve essere e tempi fattoriali.
Quindi questa è una chiamata ricorsiva e meno una.
E diciamo solo ritorno e corriamo e vediamo cosa succede.
Ora entrambi questi metodi sono invocati dal principale per primo permettimi di eseguire quell'esemplare un'ora.
Va bene così questo fattoriale e su 4 è stato richiamato dall'interno della dichiarazione irlandese di stampa qui.
Quindi lascia che esegua la chirurgia dance 24 o grand ed è uguale a quattro.
Ora vediamo cosa succede se invochiamo la versione ricorsiva, come puoi vedere ricevendo un errore chiamato
errore di overflow dello stack.
Quindi questo è ciò che stiamo ottenendo quando invochiamo la versione ricorsiva.
Questo ventiquattro qui.
Per quanto riguarda la versione non ricorsiva, il valore restituito da quello.
Quindi errore di overflow dello stack.
Ora lasciatemi spiegare questo concetto chiamato stack e stack frame.
Ma lo vedremo in dettaglio nella sezione interna della JVM.
Quindi qui stiamo andando a discuterne molto brevemente solo per darti un'idea.
Quindi, all'avvio di JVM, si ottiene un blocco di memoria dal sistema operativo.
E parte di quella memoria è chiamata meno spazio Stack Stack.
Ora lo spazio in pila ha una quantità limitata.
Ora quando viene invocato un metodo come questo.
Non così fattoriale di quattro quindi qualcosa chiamato stack frame frame dello stack è diverso dallo stack in modo da creare
uno stack frame.
E verrebbe memorizzato in STACK.
OK stack frame entra in stack.
Quindi verrebbero creati quattro frame fattoriali o quattro uno stack.
E andrebbe in pila.
Ora qui fattoriale OK sarebbe factorial o quattro e che a sua volta sta rendendo questa invocazione fattoriale di tre e
quattro che un nuovo stack frame sarebbe stato creato.
E questo verrebbe memorizzato in cima al precedente stack frame che è stato creato per davvero, naturalmente.
È così fattoriale di tre.
Quindi otteniamo un nuovo stack frame e quando una facoltà di tre viene eseguita nella rotazione successiva sarà
un fattore due.
E ciò risulterebbe nella creazione di un altro stack frame nello stack.
OK.
Quindi ora ci sono tre frame dello stack.
Così fattoriale di due saprai che verrebbe invocato di nuovo.
E questo si tradurrà in un paio di fattoriali di uno.
E poi avremo fattoriale di 0 fattoriale di meno uno e che non si fermerà mai qui.
OK.
Quindi è come un'invocazione finita ad un certo punto.
Quindi tutti questi stack stack vengono impilati nello stack e lo stack ha una memoria limitata.
E avevamo esaurito lo spazio e alla fine avremmo ricevuto questo errore chiamato errore di overflow dello stack perché
lo stack stava diventando overflow.
Quindi il problema qui è che non esiste una condizione di base.
OK.
Quindi dobbiamo mettere una condizione base in modo che la ricorsione si fermi.
E nel nostro caso la condizione di base sarebbe ed è uguale a zero in quel punto.
Sarebbe zero fattoriale e vorremmo restituirne uno.
Quindi questo è ciò che è guadagnato.
Ora ci sarebbe una chiusura ad esso.
E quindi se ci sei.
Quindi prendiamo 24.
OK.
Quindi guardiamo questo.
Quindi diciamo inizialmente ed è uguale a quattro.
Così sarebbe e tempi fattoriali fuori e meno uno.
Destra.
Potrebbero essere tre o quattro scusate quattro volte fattoriali di Quattro meno uno con la strada.
In effetti a questo punto viene invocato un totale di tre.
OK.
Quindi niente viene restituito qui.
È solo che il ritorno è lì ma lo è.
Times fattoriale di tre.
Quindi nel qual caso il controllo.
Quindi c'è una chiamata ricorsiva e il metodo dovrebbe essere eseguito ancora una volta con questo albero dei valori.
Quindi con questo il metodo viene eseguito nuovamente.
E così saremmo venuti qui e sarebbe stato tre volte fattoriale di due OK.
E questo lavoro corrisponde a due volte fattoriale di uno sul ciclo successivo.
Sarebbe una volta fattoriale di 0 su 1 fattoriale di zero viene invocato e sarà zero.
E il caso base sarebbe vero e nessuno sarebbe scritto.
OK.
Quindi, quando uno ha scritto che OK, la struttura di zero ne restituisce una.
Quindi ne avremmo uno qui.
E quindi questo è uno e questo è il ritorno qui.
Destra.
Quindi significa essenzialmente fattoriale di 1.
Quindi questo non è altro che fattoriale di uno.
Questo è ciò che sta accadendo.
Quindi stiamo dicendo che nella prossima dichiarazione avremmo scritto due in uno.
Quindi, quando viene restituito, sostituisce fattoriale di 2 con il valore scritto con 2.
E questo corrisponderebbe a 6 ora e 6 verrebbero restituiti il che significa che il fattoriale di 3
sarebbe stato sostituito con 6.
E ora siamo nella prima invocazione.
E quello sarebbe 24 e infine 24 sarebbero scritti.
Quindi con ogni invocazione il metodo viene richiamato.
Infine, quando viene raggiunta la base quando viene raggiunto il caso base, l'intero processo andrà indietro
finché non raggiungiamo la prima chiamata e quindi restituiremo quel valore e il metodo si arresta e
il metodo completa la sua esecuzione okay.
Quindi questo è il record, quindi chiama e, come puoi vedere, il tribunale è molto più pulito.
Quindi, se osservate entrambe queste implementazioni, la versione ricorsiva è molto più pulita di quanto possiamo
vedere chiaramente mentre la versione non ricorsiva ha tutto questo.
Quindi con la ricorsione ciò che otteniamo è un codice più pulito otteniamo un codice più pulito, ma sarebbe
leggermente più lento perché abbiamo come tutti questi con ogni chiamata in cui viene creato uno stock.
E questo richiederebbe un po 'di tempo e occuperebbe anche un po' di spazio per ogni invocazione e lo
stack frame verrà creato in modo tale che la parola coinvolga sia il tempo sia la base in
modo un po 'inefficiente, ma il codice è molto più più pulito ora e molto più chiaro ora e questo è ciò di cui abbiamo bisogno.
A volte possiamo compromettere l'efficienza se il codice è molto più leggibile e questo è ciò che
otteniamo dalla ricorsione.
Okay, questo è tutto.
Quindi la prossima domanda è: quando usiamo la ricorsione, la ricorsione non può essere usata per tutti i tipi di problemi.
Entra in gioco solo se il problema può essere risolto.
Siamo simili.
Alcuni problemi come in questo caso in cui ogni invocazione in cui c'è questo problema in cui dobbiamo trovare factorial fuori
dalla fine, ma che può essere affrontato via fattoriale e meno uno va bene.
Questo è un problema che può essere a sua volta indirizzato usando Rudolph e meno 2.
Quindi se questo è il tipo di problema con cui abbiamo a che fare allora possiamo usare la ricorsione.
E qui ci sono alcuni esempi di problemi che richiedono la ricorsione e ce ne sono molti altri ma questi sono alcuni
semplici esempi di cui potresti essere a conoscenza.
Uno è la ricerca binaria che riguarda la ricerca di un elemento in una lista di elementi e le Nexus
Towers di Hanoi.
Quindi, se si dispone di uno sfondo informatico, potrebbe essersi imbattuto in questo nella
classe delle strutture dati che può anche essere risolta ricorrendo alla ricorsione e successivamente alla frequenza delle parole.
Quindi se hai un documento e se vuoi cercare una parola particolare e poi vuoi cercare
quante volte quella parola appare nel documento.
Quindi può essere implementato in ogni modo immaginabile.
Quindi abbiamo guardato fattoriale.
Ora esaminiamo anche la ricerca binaria rapidamente perché la ricerca binaria è un problema di intervista di base.
Inoltre, se guardiamo anche a questo, ti daremo una migliore comprensione della ricorsione, quindi con la ricerca binaria
cercheremo un elemento tra una lista di elementi.
Diciamo che abbiamo questi elementi qui e ci sono tutte e quattro le ricerche binarie.
Il requisito è che gli elementi debbano essere ordinati per primi.
Così.
Il che significa che devono essere in ordine crescente.
In questo caso sono tutti in ordine crescente.
Quindi questo è il requisito.
Ora, se non usiamo la ricerca binaria, c'è un modo per implementarlo usando una ricerca lineare che significa che
dovresti cercare ognuno di questi elementi e controllare se l'elemento che stai cercando appare in qualsiasi
punto dell'elenco.
Quindi dovresti esaminare l'intera lista.
Ora se hai un milione di elementi scansionerai il milione di elementi nel peggiore dei casi.
Va bene.
Nel caso peggiore dovresti scansionare tutti i milioni di elementi e non troverai il tuo elemento.
In questo modo la chiamiamo ricerca lineare e l'efficienza dell'algoritmo per quella sarebbe spenta e diciamo
che è lineare.
Ora con la ricerca binaria sarà molto più efficiente a causa dell'algoritmo stesso.
E là l'efficienza l'efficienza dell'algoritmo diciamo che è logaritmica quindi sarà grande o
log n.
OK.
Quindi la ricerca binaria è più efficiente della ricerca lineare.
E vediamo come funziona.
Quindi qui abbiamo otto elementi.
Diciamo che la prima invocazione è che questa ricerca binaria non è altro che la matrice e zero non
è altro che lo zero con indice e otto è l'ultimo indice.
Quindi ci sono nove elementi che stiamo passando otto e questo è l'elemento che deve essere cercato.
Va bene.
E la ricerca binaria ritornerebbe se l'elemento è presente ovunque qui in questo caso è presente
qui.
Quindi restituirebbe la posizione dell'indice di quell'elemento.
Quindi questo sarebbe 5 0 1 2 3 4 e 5.
Ma se l'elemento non è formato allora ritornerebbe a meno 1.
Va bene.
Quindi restituirà il valore dell'indice qui.
E in sostanza ciò che fa la ricerca binaria non è la scansione dell'intero array in modo che scansiona solo
alcune aree dell'array.
Ed è per questo che è molto più efficiente e il modo in cui lo fa è che una volta
che lo invochi, la prima cosa che fa è calcolare il centro dell'array che non è altro che 0 più 8 byte 2.
Va bene.
A cui non ha nulla in cambio.
Quindi, vieni ad usare il valore fatto per così zero è l'indice inferiore dell'elemento inferiore su 8 è il più alto indicizzato, quindi non
più tardi andremo a riempire questo metodo.
Quindi la firma del metodo è anche qui.
Il primo elemento è 8.
Il secondo è indice più alto indice più basso sulla chiave per tale.
Va bene quindi sarà un vantaggio di due per zero più 8 per 2 che è per quello.
Quindi controlleremo se questo è l'elemento in questo indice, indipendentemente dal fatto che sia la chiave.
Quindi l'elemento in 4 posizioni per è 55 che non è uguale a 65.
Se fosse stato lo stesso elemento se questo fosse sessantacinque, il metodo sarebbe tornato.
Questo indice particolare come output.
Ma poiché non è il caso dopo controllerà se la P è maggiore o minore di 55.
In questo caso, sessantacinque, la nostra chiave che stiamo cercando è superiore a 55, il che significa che deve
apparire su di me e su questa parte della matrice in modo da poter ignorare tutti gli elementi che sono apparsi prima dei cinquantacinque.
E questo è ciò che ci dà l'efficienza.
Questo è ciò che rende la ricerca binaria più veloce.
Quindi stiamo saltando tutti questi elementi e ci stiamo concentrando solo su questa parte, il che
significa che ora possiamo fare una chiamata ricorsiva e dire semplicemente la ricerca binaria OK.
E abbiamo bisogno di passare la matrice e abbiamo bisogno di passare in ordine gli indici.
Quindi il mezzo era per qui.
Questo era il Met ma dal momento che l'elemento è più grande di questo deve essere da qui.
Quindi per il minimo passeremo metà più 1 e molto più in alto.
Passeremo semplicemente tutto ciò che abbiamo qui, che è 8 e l'elemento sarà passato di nuovo.
Quindi questo med plus 1 non è altro che 5.
Quindi questa è la prossima chiamata ricorsiva e per questo calcoleremo ancora una volta il risultato.
Quindi sarebbero cinque più otto 13 per 2, che sarebbero 6.
OK.
Sarebbe il sei punto cinque ma troncato a sei.
Quindi la vedremo di 6, che non è altro che questo settantuno e lo paragoniamo
a sessantacinque e sessantacinque come meno.
Quindi, questo significa che dobbiamo guardare solo a quest'area.
OK.
Quindi in precedenza sai che abbiamo limitato il nostro io a questa parte, ma ora che questa invocazione dal 65 è
inferiore a settantuno non può far parte di questo.
OK, quindi deve essere solo in quest'area, il che significa che la nostra prossima chiamata sarà qualcosa
come questa ricerca binaria di ae deve essere la parte più a sinistra.
Quindi in questo caso si vedrebbe la legge.
Quindi avremo ancora cinque sulla parte superiore sarebbe reso meno uno.
Quindi prima Matt era qui, quindi sarebbe diventato meno uno.
OK, così Matt aveva sei anni, quindi meno uno sarà cinque.
E avremo anche sessantacinque.
Ora ancora una volta.
Quindi questo è ciò che abbiamo ora che questa invocazione sia inferiore che superiore sono uguali.
E questo sarebbe il nostro caso base se si vedesse sempre più in basso, allora dovremo interrompere la nostra ricorsione
e controlleremo se l'elemento in questa posizione va bene se è sessantacinque.
OK.
E nel nostro caso alla elementare 60 se il file di posizione è effettivamente sessantacinque.
Quindi vorremmo restituire quel particolare valore.
Ecco cosa sta succedendo.
E quando torniamo.
Quindi dovremmo restituire il file di valori.
Quindi, se non fosse stato 65, sarebbe ritornato meno uno.
Ecco come funziona l'algoritmo.
Ora andiamo avanti e rapidamente raggiunto questo, quindi dovrebbe essere interessante.
Quindi abbiamo il metodo qui.
Abbiamo solo bisogno di riempire questo in modo che questo avrebbe un'efficienza logaritmica e quindi la glassatura è proviamo il
caso base.
Così abbiamo come Alan Edge in questo.
Quindi controlleremo se è uguale a bordo se questo è il caso.
OK.
Quindi dobbiamo verificare se la nostra chiave è una chiamata a una disattivazione.
Ecco come El o off.
Non importa.
Se è lo stesso, dobbiamo restituire l'indice.
Destra.
Perché abbiamo trovato il nostro elemento come vorremmo restituire meno 1.
Ora se questo non è il caso, significa che dovremmo fare una chiamata ricorsiva prima di tutto, dobbiamo
calcolare l'elemento metallico che verrebbe aggiunto più incisione per assicurarsi che le parentesi siano lì perché altrimenti senza le
parentesi questo otterrebbe una precedenza più alta.
Sarebbe inciso per 2 e poi verrà aggiunto all'errore.
Quindi abbiamo bisogno della parentesi qui.
Ora controlleremo fa se la nostra chiave è uguale alla e della metà del nostro ritorno, e se è maggiore di lui, possiamo saltare la parte
sinistra del giorno e possiamo solo cercare la parte superiore di la matrice che viene dal
MIT più uno.
Quindi diremmo la ricerca binaria eh.
Quindi nella nuova invocazione l'elemento inferiore deve essere fatto più uno.
Quindi dobbiamo passare il MIT più 1 e più alto sarebbe lo stesso.
Quindi trimestre come noi come indice superiore più alto passiamo semplicemente lo stesso.
E abbiamo anche passato la chiave.
Ora l'ultimo è se anche questo fallisce, il che significa che la chiave è inferiore a metà di quella di B.
Dobbiamo scansionare solo la parte inferiore della destra.
Tutto ok.
Quindi dovremmo
separare e una parte inferiore dell'array per la parte inferiore l'indice più basso sarebbe lo stesso indice di come.
Va bene.
E l'indice più alto nella prossima iterazione sarebbe reso meno 1.
E sarebbe la chiave.
Va bene.
Quindi questo è quello che abbiamo.
Quindi questo è l'impostazione predefinita.
Quindi se entrambi falliscono, allora arriviamo a quello di default dove key è inferiore a e off.
Quindi questo è quello che abbiamo.
Andiamo avanti ed eseguiamolo.
Quindi lascia che copi tutto questo nella questione principale.
E questo restituisce l'indice.
Quindi fammi vedere l'indice equivale a questo X
..
Quindi lasciami correre.
Quindi deve stampare bene quel valore dell'indice.
Ora se passiamo diciamo trentaquattro qui ne stamperebbe tre perché 30 40 appare nella terza
posizione.
Allo stesso modo se passi cento che non c'è.
Deve tornare meno uno.
Quindi meno uno è stato scritto.
Quindi questo è tutto quello che c'è nella ricerca binaria.
Quindi è molto più efficiente e comparato a fattoriale.
Qui ne abbiamo due in posizione ma solo in una determinata esecuzione del metodo solo uno di essi
verrebbe invocato.
Quindi è leggermente diverso qui ma dentro
Ad esempio per noi stessi e io faremo anche in luoghi simili a questo, ma non
avremmo una condizione di questo tipo.
Quindi entrambe le invocazioni sarebbero eseguite e come funzionerebbe in un modo leggermente diverso.
OK così detto e quindi sappiamo come una buona idea su come la ricorsione funzionerebbe.
E questo è tutto.
E questo codice sarà disponibile nella sezione risorse.
Grazie e buon codice.