Newsgroup: it.comp.lang.visual-basic
Titolo: Ricorsioni

Da un corso on line copio e incollo :
Function Fattoriale(ByVal n As Integer) As Long
If n >= 0 Then
If n = 0 Then
Fattoriale = 1
Else
Fattoriale = n * Fattoriale(n - 1)
End If
End If
End Function
Il numero delle righe di codice si è ridotto, a vantaggio della leggibilità.
Tuttavia, a prima vista il lettore può rimanere sconcertato dall'uso della
funzione Fattoriale all'interno della propria definizione. Ciò può apparire
come un errore. In realtà, tale tecnica è perfettamente lecita e prende il
nome di ricorsione.
Per rendersi conto del corretto funzionamento, si provi ad osservare ciò che
avviene calcolando il fattoriale di un numero qualsiasi, ad esempio 3.
Essendo n pari a 3, la funzione esegue il calcolo
Fattoriale(3)=3*Fattoriale(2)
Ma, analogamente
Fattoriale(2)=2*Fattoriale(1)
e
Fattoriale(1)=1*Fattoriale(0)
Per mezzo di una struttura If , è distinto il caso in cui n è nullo. In
questa condizione la funzione restituisce il valore 1. Quindi,
Fattoriale(3)=3*(2*(1*(1)))
Ciò concorda con la definizione matematica del fattoriale. L'uso della
ricorsione permette in alcuni casi di semplificare notevolmente la scrittura
di una funzione e di migliorarne al tempo stesso la leggibilità. Etc.etc...
---
Ho provato a far girare la funzione ma a me da sempre risultato 0 dovuto
(penso) al fatto che fattoriale vale inizialmente 0 e quindi sono
moltiplicazioni successive per 0. Ma molto più probabilmente sbaglio in
qualche cosa.

 sbaglio in qualche cosa.
A me funziona perfettamente...
bye
-- 
Esistono 10 tipi di persone: chi conosce il binario e chi no.
Gestione Ottica - Gestionale per Ottici e Programmi Gratuiti su:
http://www.nicolaottomano.it

 qualche cosa.
Si vede che hai copiato male il codice.
Quello che non capisco è perchè la funzione fattoriale venga sempre 
fatta con la ricorsione, quando sarebbe molto più semplice con un 
semplice loop (forse per puro spirito accademico):
Function Fattoriale2(ByVal n As Integer) As Long
     Dim i As Long
     Fattoriale2 = 1
     For i = 2 To n
         Fattoriale2 = Fattoriale2 * i
     Next i
End Function
-- 
Math Parser : 
http://www.neodatatype.net
FlowChart   : 
http://www.neodatatype.net/dump/flowchart/dir.asp
Sito Comune : 
http://www.it-lang-vb.net

 Il numero delle righe di codice si è ridotto, a vantaggio della leggibilità.
Aggiungo: la ricorsività raramente aumenta la leggibilità, e spesso 
complica anche la "dcodifica" del codice da parte del lettore.


> leggibilità.
Ancora io :)
Sono curioso di vedere il loro codice non ricorsivo, dato che quella 
ricorsiva è la versione ridotta :)
Ciao


 complica anche la "dcodifica" del codice da parte del lettore.
A volte puo' essere piu' leggibile una funzione ricorsiva, ma trovo
soprattutto che la ricorsivita' aumenti esponenzialmente la difficolta' di
debug (devi mantenere in testa lo stack di esecuzione).
Pero' in qualche raro caso la utilizzo, se i benefici (codice piu' breve e
piu' leggibile) sono maggiori dei difetti.
Stefano "HappyMan" (Lake Maggiore - Italy)
-- 
http://www.sgr.info
Email happyman69 (at) 
despammed.com

 semplice loop (forse per puro spirito accademico):
Perché la ricorsione (che è sicuramente molto meno efficiente ma non
certo meno semplice) ricalca la definizione induttiva del fattoriale...
Quindi in definitiva... per puro spirito accademico :)
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 complica anche la "dcodifica" del codice da parte del lettore.
Su questo non sono affatto d'accordo, io trovo un algoritmo ricorsivo
quasi sempre molto, molto più leggibile e semplice della controparte
iterativa. 
Forse è una "questione" molto soggettiva.



sinora gli unici casi in cui ho trovato la ricorsione più semplice da
gestire (raramente anche l'unica via) sono stati dei FRATTALI e una mia
pedestre implementazione di un algoritmo  di colorazione di forme
frastagliate tipo FLOODFILL (dove da un punto interno a caso partiva la
ricerca in ogni direzione di pixel contigui colorati in un certo modo).
Le prestazioni erano modeste e, soprattutto, dovevo puntare molto su
variabili globali statiche, avendo scritto sub che non avevano parametri
formali e non davano valori di ritorno. In ogni altro caso me ne venivo
fuori spesso con stack overflow. Anche così, con regioni particolarmente
vaste e complesse, qualche volta sono andato vicino (in effetti anche una
sub senza valore di ritorno e senza argomenti, e senza variabili locali,
consuma un filino di stack per scrivere almeno l'indirizzo di ritorno)
Per il resto aborrisco la ricorsione se posso evitarla.
ciao
CCCP++Mario


 complica anche la "dcodifica" del codice da parte del lettore.
mah...
l'esempio scolastico per eccellenza è il gioco della torre di hanoy.
l'ho affrontato svariati lustri fa in pascal, e in un minuto e mezzo l'ho
riscritto.
Prova un po' a farlo iterativo ;)
Private Sub Command1_Click()
  Hanoi "A", "B", "C", 3
End Sub
Function Hanoi(origine, destinazione, appoggio, n)
  If n = 1 Then
    Debug.Print "sposto un disco da " & origine & " a "; destinazione
  Else
    Hanoi origine, appoggio, destinazione, n - 1
    Debug.Print "sposto un disco da " & origine & " a "; destinazione
    Hanoi appoggio, destinazione, origine, n - 1
  End If
End Function
-- 
Ciao, Silv:o)
PS conosco un truccaccio per risolverlo in maniera meno che iterativa. O
meglio: lo conoscevo, ma gooooooogle ricorda tutto ;)

... è insostituibile nell'esplosione di una distinta base ad n
livelli: con poche righe risolvi elegantemente quello che
difficilmente può essere risolto in altri modi.
Ciao MArco

 Ciao MArco
Sě, i programmi a livelli sono gli unici che reputo scrivibili con la 
ricorsione, come ad es. lo scorrimento di un albero.
Ciao



debug:
sposto un disco da A a B
sposto un disco da A a C
sposto un disco da B a C
sposto un disco da A a B <<< ???
sposto un disco da C a A
sposto un disco da C a B
sposto un disco da A a B <<< ???
se lo scopo del gioco vuole essere permutazione senza ripetizioni non
funziona bene la ricorsione, altrimenti non mi e' chiaro lo scopo del gioco.
beppe

 
Le torri di hanoi č uno dei problemi piů classici nell'ambito 
dell'informatica accaemica.
Puoi trovare tantissimi link in rete.
Brevemente consiste in una serie di dischi di dimensioni concentriche 
infilati in modo decrescente in un "palo" (ottenendo una struttura tipo 
torre di babele) e avendo a disposizione altri due "pali" su cui 
spostare i dischi lo scopo č quello di spostare la torreda un palo 
all'altro con i vincoli:
- si puň spostare un solo disco alla volta
- tutti i dischi devono essere posizionati in uno dei tre pali (non si 
puň tenerne uno in mano, per intenderci, mentre se ne spostano altri)
- un disco puň stare solo a terra o su un disco di dimensioni maggiori.
Ciao


 iterativa. 
Io sono d'accordo con te e con termoPilucco
termoPilucco
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 ricorsione, come ad es. lo scorrimento di un albero.
Infatti, sto caricando una TreeView con collegamenti padre-figli
figli che diventano padri-figli, ecc.
senza la ricorsione non credo riuscirei a costruire l'albero
Ave
giuseppeD

 funziona bene la ricorsione, altrimenti non mi e' chiaro lo scopo del
gioco.
già Zanna ti ha risposto sul gioco della torre di Hanoi.
Forse stampando anche il disco da spostare diventa più chiaro:
Debug.Print "sposto il disco " & n & " da " & origine & " a " & destinazione
Poi magari mettendo Sub al posto di Function, ma tanto VB si pappa tutto!
L'output diventerebbe:
sposto il disco 1 da A a B
sposto il disco 2 da A a C
sposto il disco 1 da B a C
sposto il disco 3 da A a B
sposto il disco 1 da C a A
sposto il disco 2 da C a B
sposto il disco 1 da A a B
che ha questa interpretazione grafica (usare font non a dimensione fissa):
  "A"       "B"       "C"
   |         |         |
  [1]        |         |
 [ 2 ]       |         |
[  3  ]      |         |
sposto il disco 1 da A a B
  "A"       "B"       "C"
   |         |         |
   |         |         |
 [ 2 ]       |         |
[  3  ]     [1]        |
sposto il disco 2 da A a C
  "A"       "B"       "C"
   |         |         |
   |         |         |
   |         |         |
[  3  ]     [1]     [  2  ]
...
  "A"       "B"       "C"
   |         |         |
   |         |         |
   |       [ 2 ]       |
  [1]     [  3  ]      |
sposto il disco 1 da A a B
  "A"       "B"       "C"
   |         |         |
   |        [1]        |
   |       [ 2 ]       |
   |      [  3  ]      |
-- 
Ciao, Silv:o)

 fissa):
ehm... usare font *a* dimensione fissa :-)
-- 
Salutoni
Sergio
per rispondere... togli il group dall'indirizzo

 
SEMPRE nei NG ;)
Ciao


 ehm... usare font *a* dimensione fissa :-)
Lo vedi che era meglio lasciare "non proporzionali"!
Mi sono detto: perché usare una negazione quando c'è una forma diretta.
Meglio comunque l'inglese: fixed fonts o monospaced fonts.
-- 
Ciao, Silv:o)