1 / 36

Linguaggi di programmazione I La ricorsione

Linguaggi di programmazione I La ricorsione. Prof. Luigi Di Lascio Lezione 10. Funzioni Ricorsive. 1 è un numero naturale Il successore di un numero naturale è un numero naturale.

mervyn
Télécharger la présentation

Linguaggi di programmazione I La ricorsione

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linguaggi di programmazione ILa ricorsione Prof. Luigi Di Lascio Lezione 10 LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  2. Funzioni Ricorsive • 1 è un numero naturale • Il successore di un numero naturale è un numero naturale La definizione di un concetto matematico è detta ricorsivo se questo è definito (totalmente o parzialmente) in termini di se stesso In particolare: La definizione ricorsiva di una funzione utilizza la funzione stessa e una versione più semplice di questa LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  3. Esempio: la definizione ricorsiva del fattoriale di n • 0!=1 • 2. n!=n*(n-1)! Se n=0 allora fat(n)=1 altrimenti fat(n)=n*fat(n-1) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  4. long int fat(int n){ long int fattoriale;if(n==0) fattoriale=1;elsefattoriale=n*fat(n-1); return fattoriale;} Esempio: la definizione ricorsiva del fattoriale di n, l’implementazione Se n=0 allora fat(n)=1 altrimenti fat(n)=n*fat(n-1) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  5. Il proccesso ricorsivo LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  6. Come evidenziare il processo ricorsivo long int fat(int m) { long int fattoriale; if(m==0) fattoriale=1; else fattoriale=m*fat(m-1); printf("fattoriale(%d) = %d\n",m,fattoriale); return fattoriale; } fattoriale(0) = 1 fattoriale(1) = 1 fattoriale(2) = 2 fattoriale(3) = 6 fattoriale(4) = 24 fattoriale(5) = 120 RIS. FINALE: fattoriale di 5 = 120 Premere un tasto per continuare . . . LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  7. Definizioni ricorsive/1 Vita quotidiana (anzi serale e mangereccia) L’ordine di una o più pizze può essere cosi formulata: ordine := <pietanza> <conto> ordine : = <pietanza> <ordine> pietanza := margheritabruschetta vino conto := somma da pagare LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  8. Definizioni ricorsive/2 Definizioni ricorsive di libro libro := <capitolo> libro: = <capitolo> <libro> <capitolo >:= qui definizione LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  9. Definizioni ricorsive/3 Definizioni ricorsive di libro, capitolo e paragrafo libro := <capitolo> libro: = <capitolo> <libro> capitolo := <paragrafo> capitolo : = <paragrafo><capitolo> paragrafo : = <testo> paragrafo := <testo><paragrafo> testo := <parola> testo: = <parola><testo> parola:= una stringa presente sul vocabolario di italiano LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  10. Definizioni ricorsive: in generale /1 Se questo è il caso più semplice, allora calcola la soluzione, altrimenti ridefinisce il problema usando la ricorsione Somma di n numeri interi Caso più semplice: la sequenza è costituita da un solo numero a[0]. In tal caso: somma = a[0] Parte ricorsiva: somma(n) = a[n-1]+somma(n-1) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  11. La funzione ricorsiva somma(n) long int somma(int a[], int dim) { if(dim==1) return a[dim-1]; else return (somma(a,dim-1)+a[dim-1]); } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  12. Definizioni ricorsive: in generale /2 Se C è il caso più semplice, allora calcola la soluzione immediata, altrimenti ridefinisci il problema mediante suoi sottoproblemi, usando la ricorsione Esempio: Definizione ricorsive di potenza di base b ed esponente intero positivo n: potenza(b,n) Se n=0 allora potenza(b, 0) = 1, altrimenti potenza(b,n)=b*potenza(b,n-1) Caso semplice: potenza(b, 0) = 1 Parte ricorsiva: ridefinire il problema mediante una definizione ricorsiva di più sottoproblemi: potenza(b,n)=b*potenza(b,n-1) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  13. La funzione ricorsiva potenza(b, n) long int potenza(int base, int esp) { long int pot; /*printf("dati di input: base=%d, esp=%d\n",base,esp);*/ if(esp==0) pot=1; else pot=base*potenza(base,esp-1); /*printf("potenza(%d, %d) = %d\n",base,esp,pot);*/ return pot; } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  14. Permutazioni, disposizioni, combinazioni Permutazioni semplici di n oggetti distinti P(n) = n! Disposizioni semplici di n oggetti distinti presi k a k Dn,k = n  (n  1)  (n  2)  ...  (n  k + 2)  (n  k + 1)= n!/(n-k)! Combinazioni semplici di n oggetti distinti presi k a k Cn,k = Dn,k/k!=n!/(k!(n-k)!) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  15. Disposizioni Disposizioni semplici di n oggetti distinti presi k a k 2. D(n, k) = n!/(n-k)! = n*(n-1)!/[(n-1)-(k-1)]=n*D(n-1, k-1) 1. D(n,1) = n int dispo(int n, int k) { if(k==1) return(n); else return(n*dispo(n-1, k-1)); } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  16. Combinazioni Combinazioni semplici di n oggetti distinti presi k a k: C(n,k)= D(n,k)/k! int comb(int n, int k) { return(disp(n, k)/fat(k)); } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  17. Combinazioni Combinazioni semplici di n oggetti distinti presi k a k 2. C(n,k)= n!/(k!(n-k)!)=[n*(n-1)!]/[k*(k-1)!(n-1-(k-1))]= = n/k * C(n-1,k-1) = = n*C(n-1,k-1)/k 1. C(n,1) = n Un esercizio per voi! LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  18. La successione di Fibonacci F(0) = 0 F(1) = 1 F(n) = F(n  1) + F(n  2) Note storiche: Leonardo Fibonacci, 1170-1250, noto come Leonardo da Pisa, introdusse il sistema numerico arabo posizionale in Europa (Libro dell’abaco) Per esempio F(2) = 1 + 0 = 1 F(3) = 1 + 1 = 2 F(4) = 2 + 1 = 3 F(5) = 3 + 2 = 5 F(6) = 5 + 3 = 8 F(7) = 8 + 5 = 13 LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  19. #include <stdio.h>long int fibo(int);main(){int n; long int f;printf("\nInserire n: \t");scanf("%d", &n);f=fibo(n);printf(“Termine di posto %d = %ld\n", n, f);} La successione di Fibonacci /1 LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  20. long int fibo(int n) {if(n==0) return(0);else if(n==1) return(1); else return(fibo(n-1)+fibo(n-2));} La successione di Fibonacci /2 F(0) = 0 F(1) = 1 F(n) = F(n  1) + F(n  -2) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  21. long int fibo(int n) {switch(n){ case 0: return(0);break; case 1: return(1);break; default: return(fibo(n-1)+fibo(n-2)); break;} La successione di Fibonacci /3 F(0) = 0 F(1) = 1 F(n) = F(n  1) + F(n  -2) LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  22. Altri problemi risolti ricorsivamente: Contare le occorrenze di un carattere in una stringa Ricerca lineare ricorsiva Ordinamento per inserimento ricorsivo LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  23. Contare le occorrenze di un carattere in una stringa O la stringa è vuota oppure essa contiene caratteri. In tal caso le occorrenze del carattere che interessa sono la somma delle occorrenze nella coda della stringa +1, se il primo elemento della stringa è proprio il carattere sotto osservazione. int conta(char ch, char *str) { int ris; If(str[0]==‘\0’) ris=0; else if(ch==str[0]) ris=1+conta(ch,&str[1]); else ris=conta(ch,&str[1]); return (ris); } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  24. Contare le occorrenze di un carattere in una stringa include <stdio.h> #include <stdlib.h> int conta(char, char *); int main() { int y=0; y = conta('c',"stcrincgca"); printf(" d = %d\n", y); system("PAUSE"); return 0; } int conta(char ch, char *stri) { int ris; if(stri[0]=='\0') ris=0; else if(ch==stri[0]) ris=1+conta(ch,&stri[1]); else ris=conta(ch,&stri[1]); return (ris); } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  25. int appartiene(int a[], int dim, int elem){ if(a[dim-1]==elem) return TROVATO; else { dim=dim-1; if(dim>=1) appartiene(a,dim,elem); else return NON_TROVATO; } } Ricerca lineare ricorsiva LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  26. Ordinamento per inserimento ricorsivo/1 Se l’array ha un solo elemento allora non fare nulla, perché l’array è ordinato altrimenti ordina i primi n-1 elementi dell’array e quindi inserisci l’elemento di posto n, salvaguardando l’ordinamento LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  27. void ord(int a[], int dim){ int el; if (dim==1) return; else { el=a[dim-1]; dim=dim-1; ord(a,dim); inserisci(el,a,dim+1); }} Ordinamento per inserimento ricorsivo/2 LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  28. Complementi LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  29. Disposizioni int dispo2(int k, int n) { return(fat(n)/fat(n-k)); } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  30. Moltiplicazione, potenza, somma, somma di quadrati /1 #include <stdlib.h> #include <stdio.h> #include <string.h> #define DIM 5 int molt(int, int); long int potenza(int, int); long int somma(int [], int); long int sommaq(int [], int); LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  31. Moltiplicazione, potenza, somma, somma di quadrati /2 int main() { /* valido solo per m, n>0 */ int base, m=2, esp, n=3,p; long int pot; int a[DIM]={1,2,3,4,5}; p=molt(m,n); printf("%d x %d = %d\n",m,n,p); printf("\n\n"); base=m; esp=n; pot=potenza(base,esp); printf("%d ELEVATO A %d = %d\n\n\n",m,n,pot); printf("somma = %ld\n\n",somma(a,DIM)); printf("somma dei quadrati= %ld\n\n",sommaq(a,DIM)); system("PAUSE"); return 0;} LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  32. Moltiplicazione, potenza, somma, somma di quadrati /3 int molt(int m, int n) { int prodotto; printf("dati di input: m=%d, n=%d\n",m,n); if(n==1) prodotto=m; else prodotto=m+molt(m,n-1); printf("molt(%d, %d) = %d\n",m,n,prodotto); return prodotto; } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  33. Moltiplicazione, potenza, somma, somma di quadrati /4 long int potenza(int base, int esp) { int pot; printf("dati di input: base=%d, esp=%d\n",base,esp); if(esp==0) pot=1; else pot=base*potenza(base,esp-1); printf("potenza(%d, %d) = %d\n",base,esp,pot); return pot; } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  34. Moltiplicazione, potenza, somma, somma di quadrati /5 long int sommaq(int a[], int dim) { if(dim==1) return a[dim-1]*a[dim-1]; else { return (sommaq(a,dim-1)+a[dim-1]*a[dim-1]); } } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  35. Ricerca ricorsiva con indicazione della posizione /* al momento della chiamata trovato=0 */ void appartiene(int a[], int dim, int elem, int *posiz, int *trovato) { if(a[dim-1]==elem) {*trovato=1; *posiz=dim-1;} else { dim=dim-1; if(dim>=1)appartiene(a,dim,elem,posiz,trovato); } } LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

  36. Proposte di lavoro • Invertire un array di dati di tipo int • Invertire una parola • Ricercare un carattere in una stringa e riportare la posizione • Ricerca una parola in un array di parole • Calcolare l’intersezione tra due insiemi • Calcolare l’unione tra due insiemi • Calcolare il complemento di A in B LdL - LP1 - ver. 6 - lez. 10 - aa 05-06

More Related