|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Oct 2009
Città: Lecce
Messaggi: 1356
|
Funzione Ricorsiva in C
Salve a tutti, mi sto affacciando alla programmazione in C da un po' di tempo, ma non riesco a capire come si faccia una funzione ricorsiva, fra gli esempi portava il calcolo del fattoriale, e lì qualcosina c'ho capito, ma del tipo calcolare la somma di un array di interi mi sembra una cosa criptica
Qualcuno di buon cuore può darmi una mano?
__________________
Oggetti attualmente in vendita:HD7950 + Phenom II 1090T /// HAF 922 /// XFX R9 280X 230€ |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jun 2003
Messaggi: 15829
|
Per esempio
Codice:
int somma(int A[]; int n)
{
if (n=0) {
return 0
} else {
return A[n] + somma(A, n-1)
}
}
"n" il numero di elementi La logica è che la somma di un vettore è la somma del primo elemento più la somma del restante pezzo, la somma del restante peezzo, è la somma del primo elemento più la somma del restante pezzo, e così via.... finchè sei arirvato alla fine (return 0) che corrisponde al valore dell'elemento dopo la fine del vettore Ultima modifica di Simonex84 : 16-02-2015 alle 12:35. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Oct 2009
Città: Lecce
Messaggi: 1356
|
Quote:
return A[n]+somma(A,n-1) vuol dire prendere l'elemento di A puntato da n e richiamare la funzione somma che andrà a prendere l'elemento n-1 di A?
__________________
Oggetti attualmente in vendita:HD7950 + Phenom II 1090T /// HAF 922 /// XFX R9 280X 230€ |
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Jun 2003
Messaggi: 15829
|
Quote:
Leggi l'EDIT che ho aggiunto sopra |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12960
|
Quote:
1) Non controlli se l'indice è negativo (conviene passare un unsigned) 2) A[n] provoca un buffer overflow, in C gli indici degli array vanno da 0 a N-1. 3) Per le variabili è meglio usare nomi con lettere minuscole Codice:
int somma(int a[], size_t n)
{
if (n == 0) return 0;
return a[n-1] + somma(a, n-1);
}
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Jun 2003
Messaggi: 15829
|
Quote:
a parte gli scherzi l'ho buttato giù al volo prima di andare a pranzo, comunque anche la tua non va bene perchè così non sommi l'elemento in prima posizione a(0) così invece dovremmo esserci Codice:
int somma(int a[], int n)
{
if (n < 0) return 0;
return a[n-1] + somma(a, n-1);
}
|
|
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12960
|
Quote:
Quando n = 1 prendo a[0], quindi in teoria dovrebbe funzionare. La cosa più semplice per capirlo è considerare che n indica il numero di elementi da sommare. Quindi mi sa che la mia è ancora valida Cmq spero che i nostri ragionamenti aiutino nasio a capire. Ultima modifica di WarDuck : 16-02-2015 alle 15:10. |
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: May 2008
Città: Torino - Valenza (AL)
Messaggi: 1221
|
Quote:
ma in quest'ultima chiamata fai il check if n==0 e restituisci subito 0, non il contenuto di a[0] quindi correggendo (io non lo scriverei mai così) sarebbe: Codice:
int somma(int a[], size_t n)
{
if (n == 0) return a[n];
return a[n-1] + somma(a, n-1);
}
resta il fatto che la somma degli elementi di un array si potrebbe senza problemi calcolare iterativamente, aggirando a monte il problema
Ultima modifica di M@Rk0 : 16-02-2015 alle 16:43. |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2788
|
Quando n=1 return a[n-1] + somma(a, n-1) cioè a[0] + somma(a, 0) cioè a[0] + 0 quindi è corretto
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jun 2003
Messaggi: 15829
|
in questo esempio usare la ritorsione è una forzatura a scopo didattico (userei anche io un ciclo), però è bene prenderci la mano perché una tecnica di programmazione molto utile
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12960
|
Quote:
L'ultimo passo rimane: a[0] + 0, che quindi è corretto Chiaro, ma l'autore del thread voleva delucidazioni sulla versione ricorsiva. |
|
|
|
|
|
|
#12 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Al di là della questione sugli indici del vettore restituito, il problema credo sia un altro, ovvero che ti concentri troppo sull'aspetto implementativo e poco sull'aspetto matematico. Devi provare a scrivere la funzione ricorsiva prima in termini matematici e poi vedrai che tradurla in qualsiasi linguaggio di programmazione diventa un problema banale.
Il fattoriale, che già ti è chiaro può essere definito come Codice:
factorial 0 = 1 factorial n = n * factorial (n - 1) Il codice significa la seguente cosa. Il fattoriale di 0 è uguale 1, mentre il fattoriale di un generico numero n è uguale a n moltiplicato il fattoriale di n-1. Mi sembra piuttosto semplice da interpretare. Personalmente sono abituato a scrivere prima il caso generale (la seconda riga dell'esempio) e poi il caso base (la prima riga). Questo perché in pratica il caso base serve come condizione di arresto della ricorsione. Ripeto, è solo un consiglio e non una regola. Il tuo problema di calcolare la somma di un vettore può quindi essere risolto come: Codice:
sum [] = 0 sum (head:tail) = head + sum tail Codice:
vettore = [3,5,6,7,8,2] quindi head = 3 tail = [5,6,7,8,2] Questo è quello che dovrebbe essere il tuo modo di pensare, ad alto livello aiutandoti con una notazione vicina a quella matematica. Ora purtroppo per te implementare questa funzione ricorsiva in C non può essere fatto in maniera diretta usando i vettori, quindi quello che si fa è usare un contatore che scorre il vettore durante la ricorsione. Usando uno pseudo-codice simile a quello usato finora, ma più vicino al C: Codice:
sum vect index =
if index < 0
return 0
else
return vect[index] + sum vect (index-1)
Per questo problema, come sottolineato anche da altri utenti, la ricorsione è un po' una forzatura, soprattutto perché l'implementazione in C con vettori forza l'uso di un contatore. Al contrario, usando un altro linguaggio che supporta nativamente le liste il codice sarebbe risultato pressoché identico a quello che ho scritto prima in Haskell. Ad esempio in Python: Codice:
def sumList(list):
if len(list)==0:
return 0
else:
return list[0] + sumList(list[1:])
|
|
|
|
|
|
#13 | ||||
|
Senior Member
Iscritto dal: May 2008
Città: Torino - Valenza (AL)
Messaggi: 1221
|
Quote:
Quote:
Quote:
Quote:
|
||||
|
|
|
|
|
#14 |
|
Member
Iscritto dal: Dec 2013
Messaggi: 90
|
Codice:
int somma(int v[], int n)
{
return ( --n ) ? v[n] + somma(v,n) : v[n];
}
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jun 2003
Messaggi: 15829
|
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Oct 2009
Città: Lecce
Messaggi: 1356
|
Quote:
__________________
Oggetti attualmente in vendita:HD7950 + Phenom II 1090T /// HAF 922 /// XFX R9 280X 230€ |
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ovviamente assumendo che n > 0. Per n == 0 va in crash.
__________________
In God we trust; all others bring data |
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
Codice:
int somma(int a[], size_t n)
{
if (n == 0) return 0;
return a[n-1] + somma(a, n-1);
}
__________________
In God we trust; all others bring data |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:58.




















