Diretta Laboratorio di Programmazione M-Z Docente: Dott.ssa Alessandra Lumini alessandra.lumini@unibo.it Università di Bologna, Sede di Cesena
Divide et impera Dividere un problema in sottoproblemi più semplici da risolvere. La soluzione del problema principale viene ricavata combinando le soluzioni dei sottoproblemi risolti. Approccio top down. Molto studiata (informatica teorica, teoria della calcolabilità) ed utilizzata (algoritmi di ordinamento, parsing, calcolo numerico). Schematicamente: 1. Divide: il problema viene suddiviso in parti più piccole. 2. Impera: i sottoproblemi vengono risolti. 3. Combina: i risultati vengono ricombinati. Diretta
Definizione Una funzione è detta ricorsiva se chiama se stessa. Una funzione ricorsiva risolve direttamente solo i casi particolari di un problema, detti casi base. Quando una funzione ricorsiva chiama se stessa, sospende l esecuzione ed esegue la nuova chiamata. L esecuzione della funzione chiamante riprende una volta che la funzione chiamata è terminata. La sequenza di più chiamate ricorsive termina quando la più interna (annidata) incontra uno dei casi base. Schematicamente: Diretta 1. Se la funzione incontra un caso base: restituisce un risultato 2. Altrimenti: viene richiamata su dati semplificati (passo ricorsivo)
Diretta Divisione Divisione a/b eseguita per sottrazioni successive: 0, se a = 0 div(a, b) = 1, se b = 0 1 + div(a b, b) altrimenti (1) Diretta int idiv ( int num, int den ){ if(num == 0) // Caso base 1 ( impera ) return 0; if(den == 0) // Caso base 2 ( impera ) return -1; return 1+iDiv (num -den, den ); // passo ricorsivo ( divide ) Cosa succede se a non è divisibile per b?
Diretta Serie n i=1 i sum(n) = { 1, se n = 1 n + sum(n 1) altrimenti (2) Diretta n i=1 i 2 sum2(n) = { 1, se n = 1 n 2 + sum2(n 1) altrimenti (3) n i=1 a (i/a) { a (1/a), se n = 1 serie(a, n) = a (n/a) + serie(a, n 1) altrimenti (4)
Ricorsion Mutua Si parla di ricorsione indiretta quando nella definizione di un metodo compare la chiamata ad un altro metodo il quale direttamente o indirettamente chiama il metodo iniziale. Scrivere la funzione ricorsiva che stampa k 0 seguiti da k 1. Diretta void print1 ( int k); void print0 ( int k) { if (k >0) { printf ("0"); print1 (k); void print1 ( int k) { if (k >1) { print0 (k -1) ; printf ("1"); Posso farlo anche con una funzione ricorsiva diretta? Modificare la funzione in maniera tale che la sequenza di 0 e 1 sia separata dal -.
Sequenza caratteri di input Diretta Prendere in input una sequenza di caratteri fino a un terminatore (CR=10) e stamparla in verticale void verticalstring () { char c; c = getchar (); if (c!= 10) { printf ("%c\n", c); verticalstring (); Invertire la stringa re anche la cardinalità della sequenza
Diretta 1. Scrivere una funzione ricorsiva che restituisca la somma di tutti gli interi in un range n 1, n 2. 2. Si scrivano 2 programmi, uno iterativo e uno ricorsivo, che invertano le cifre di un numero intero n. 3. Scrivere una funzione che calcola sin(x) utilizzando lo sviluppo di Taylor fino al termine n-esimo. sin(x) n ( 1) k x 2k+1 (2k + 1)! k=0
4. I coefficienti binomiali. ( n k) forniscono il numero delle combinazioni semplici di n elementi di classe k. Il matematico Pascal scoprì disponendoli su un triangolo ogni numero al suo interno è pari alla somma dei due posti ( sopra di esso. n ( k) = n 1 ) ( k 1 + n 1 ) k per 0 < k < n ) = 1 per k = 0, k = n ( n k Diretta 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 Scrivere la funzione ricorsiva binomiale e richiamarla per stampare il tringolo di Pascal (Tartaglia)