CORSO DI PROGRAMMAZIONE II

Slides:



Advertisements
Presentazioni simili
INFORMATICA Altre Istruzioni di I/O
Advertisements

RICORSIONE: DEFINIZIONI RICORSIVE
Funzioni In C++ le funzioni sono caratterizzate da un nome, dal tipo della variabile ritornata e da una lista di parametri (opzionali) La lista dei parametri.
Sottoprogrammi: funzioni e procedure
Ricorsione Procedure e funzioni ricorsive. Definizioni Un oggetto si dice ricorsivo se è definito totalmente o parzialmente in termini di sé stesso La.
Struttura di un programma
Procedure e funzioni ricorsive
MATLAB.
MATLAB. Scopo della lezione Programmare in Matlab Funzioni Cicli Operatori relazionali Esercizi vari.
1 Informatica Generale Susanna Pelagatti Ricevimento: Mercoledì ore presso Dipartimento di Informatica, Via Buonarroti,
Le funzioni.
Soluzioni Esercizi 3 Numeri Interi.
Lez. 41 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Programmazione.
La ricorsione Simulazione. Il Main /* Programma che usa una funzione ricorsiva*/ #include #define MAX_N 8 main() int valore, dato; printf(Introduci n:
TERNE PITAGORICHE Obiettivi dell’esercitazione
Introduzione agli algoritmi. Definizione Sistema di regole e procedure di calcolo ben definite che portano alla soluzione di un problema con un numero.
Iterazione enumerativa (for)
Tail recursion: esempio
Esercizi su alberi binari di ricerca
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2007/2008 Corso di Programmazione 1 a.a.2007/2008 Prof.ssa Chiara Petrioli Corso di Laurea.
Algoritmi Politecnico di Milano C Primi programmi Politecnico di Milano.
Informatica 2. Concetti fondamentali di programmazione Programmare vuol dire scrivere un algoritmo in un linguaggio che faccia funzionare un calcolatore.
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab m-file m-file script script Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali.
MATLAB.
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali Indipendenza lineare,
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali Esercizi vari Esercizi.
CORSO DI PROGRAMMAZIONE II
CORSO DI PROGRAMMAZIONE II Introduzione alla ricorsione
Programmazione Mod A - Cap 2 - prof. Burattini
APPUNTI SUL LINGUAGGIO C
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Esercizi su alberi binari
INFORMATICA Altre Istruzioni di I/O. © Piero Demichelis 2 Funzioni di I/O Per la lettura e la scrittura da videoterminale il C prevede numerose istruzioni.
Esercizi FUNZIONI Passaggio di parametri per valore, variabili e tipi locali e globali, prototipo.
Strutture di controllo in C -- Flow Chart --
Esercizi Interi.
Esercizi 4 Soluzioni Calcolo combinatorio.
Le funzioni.
Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),
AN FI Iterazione&Invarianti Il ragionamento iterativo Gli invarianti di ciclo.
Calcolo del Massimo Comun Divisore
Equazione di secondo grado.
Lezione 6 Strutture di controllo Il condizionale
void binario(int n); …………………
G. Amodeo, C. Gaibisso Programmazione di Calcolatori Lezione XII Le funzioni Programmazione di Calcolatori: le funzioni 1.
Massimo Comun Divisore
Un esempio: Calcolo della potenza n-esima di un numero reale
Lo sviluppo top down Le funzioni
Passaggio di parametri per indirizzo
Radice quadrata di un numero
Esercizi Liste.
Corso di Programmazione in Java – Esercizio n° 001
Tail recursion: esempio
Esercizi La distanza di hamming tra due interi x e y si definisce come il numero di posizioni nella rappresentazione binaria di x e y aventi bit differenti.
Esercizi su alberi binari di ricerca
ND-partizione (A) n   A  somma  0 M  1/2 (  a i ) for i  1 to n do S[i]  choice ({true, false}) if S[i] then somma  somma + a i if somma > M then.
Ripetizione La vera potenza dei programmi per computer risiede nella capacità di ripetere lo stesso calcolo o sequenza di istruzioni più volte, ogni volta.
alberi completamente sbilanciati
La ricorsione.
Flusso Statico e Dinamico 20/03/2006. Codice da Interpretare int valore; valore = funz(); if( valore > 0 ) { [codice1] } else { [codice2] } return valore;
Top STACK Top Le operazioni fondamentali che si fanno sugli stack sono: riempimento e svuotamento. Questo implica che durante lo svolgimento del programma.
Informatica 4 Funzioni. FUNZIONE: definizione MATEMATICA Relazione (o applicazione) binaria tra due insiemi A e B che associa a ogni elemento di A un.
Allievi Elettrici - AA Le funzioni ricorsive in C
CORSO DI PROGRAMMAZIONE II
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Esercizio 14 – chiamata di una procedura Il codice deve: Passare due parametri alla procedura ‘salva’ Questa procedura deve salvare i due parametri nel.
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Informatica 4 La ricorsione. Definizione di ricorsione Ricorsione è la proprietà di quei programmi che, all’interno delle istruzioni che li compongono,
Linguaggio C: Funzioni e Puntatori Laboratorio di Programmazione Gruppo 1.
Transcript della presentazione:

CORSO DI PROGRAMMAZIONE II Lezione 6 Ricorsione lineare prof. E. Burattini a.a. 2009-2010

Esaminiamo ora un altro esempio: Il calcolo della potenza ennesima di un dato numero.

DIMOSTRAZIONE PER INDUZIONE POTENZE Vogliamo dimostrare che S(n): a) q.e.d. caso base Poniamo n=1 avremo che è quindi dimostrato vero passo induttivo Dobbiamo ora dimostrare che b) Avendo supposto vero l’asserto sostituiamo in b) il valore che si ottiene da a)

Codice della funzione PotenzaN. Si presume che siano stati assegnati Xre, numero che si vuole elevare a potenza e N potenza alla quale si vuole elevare Xre. Si noti che l’algoritmo è simile a quello per il calcolo della somma dei numeri interi, fatto salvo per il caso base che vale 1, infatti (Xre)0=1. double PotenzaN(double Xre,int N) { if (N==0) return 1; else return Xre*PotenzaN(Xre,N-1); } Di seguito si mostra sia lo stack dei processi che la modifica dei parametri man mano che il processo avanza. L’esempio è fatto per Xre=0.9 e N=6

double PotenzaN(double Xre,int N) { if (N==0) return 1; else No PotenzaN(0.9,2) PotenzaN(0.9,1) N=0? No N=0? No PotenzaN(0.9,0) N=0? Si PotenzaN 1 PotenzaN 0.9* PotenzaN 0.9* PotenzaN 0.9* 0.9*PotenzaN(0.9,0) =1 double PotenzaN(double Xre,int N) { if (N==0) return 1; else return Xre*PotenzaN(Xre,N-1); } =0.9*1 0.9*PotenzaN(0.9,1) =0.9*0.9 0.9*PotenzaN(0.9,2) =0.9*0.9*0.9 0.9*PotenzaN(0.9,3)

ESERCIZIO Scrivere una funzione ricorsiva che, assegnati due interi N1 ed N2, restituisca la somma di tutti gli interi compresi tra N1 ed N2.

Esercizio Scrivere un algoritmo ricorsivo per determinare se un assegnato numero intero positivo N è primo. Si dimostra che un numero è primo se nell’intervallo 1.. non ha divisori tranne il numero 1.

cout<<"Inserisci un numero intero: "; cin>>N; ESERCIZIO Scrivere un algoritmo ricorsivo per determinare se un assegnato numero intero positivo N è primo. int main(){ int N; cout<<"Inserisci un numero intero: "; cin>>N; int radN=sqrt(N); if (primo(N, radN) cout<<" Il numero "<<N<<" e' primo "<<endl; else cout<<" Il numero "<<N<<" non e' primo "<<endl; system("PAUSE"); }

bool primo(int n,int P) { if (P<2) return true; else if (n%P==0) return false; return primi(n,P-1); } // Caso base: non ha trovato alcun divisore di kn // Esiste almeno un divisore di kn diverso da 1 // Chiamata ricorsiva su un valore di kn minore Allegato: numeriprimi

Esercizio Scrivere un algoritmo ricorsivo per determinare quanti numeri primi ci sono in un preassegnato intervallo K1..K2 di numeri interi positivi. Allegato: NumeriPrimiIntervallo3

(300 A.C.) Siano m ed n due numeri naturali e supponiamo sia m>n ALGORITMO DI EUCLIDE PER IL CALCOLO DEL MASSIMO COMUN DIVISORE (300 A.C.) Siano m ed n due numeri naturali e supponiamo sia m>n 1 Si divide m per n 2 Se il resto è zero allora n è il MCD tra m e n. 3 Se il resto è diverso da zero torna al primo passo scambiando m con n e n con r (cioè dividi n per r)

Nel lucido seguente è mostrata una interpretazione geometrica dell’algoritmo di Euclide. Si vuole il MCD dei numeri M e N rappresentati ciascuno da un segmento di lunghezza M e N. Il segmento restante dalla differenza tra M e N, detto R viene successivamente confrontato con N che quindi assume il ruolo di M nel caso precedente. Si prosegue fin quando i due segmenti che si confrontano non hanno la stessa lunghezza. Il valore ultimo di R sarà il MCD tra M e N.

M ALGORITMO DI EUCLIDE N R R R’ R’ R’ MCD=

Un algoritmo ricorsivo per il calcolo del MCD tra M e N può essere il seguente: Pseudo codice IF M o N sono valori che rappresentano una soluzione valida MCD  valore della soluzione (M o N) ELSE MCD  MCD(N, M MOD N)

Di seguito si mostrano le versioni iterativa e ricorsiva per il calcolo del MCD secondo l’algoritmo di Euclide. VERSIONE ITERATIVA VERSIONE RICORSIVA int MCD(int m,n) { int Resto=m%n; while (Resto !=0) { m=n; n=Resto; Resto= m % n; } return n; int MCD(int m,int n) { if (n==0) return m; else return MCD(n, m%n ) }

Nel lucido seguente viene mostrato un esempio di calcolo del MCD, tra 30 e 18, secondo Euclide, con un algoritmo ricorsivo, tramite la rappresentazione in termini di processi aperti, variazioni del valore delle variabile durante il calcolo, rappresentazione geometrica.

MCD(int m, n) MCD(30,18) MCD(18,12) MCD(12,6) MCD(6,0) No N=0? No N=0? No N=0? Si MCD MCD MCD MCD(18,12) MCD(12,6) MCD(6,0) MCD 6 int MCD(int m,int n) { if (n==0) return m; else return MCD(n, m%n ); } MCD(6,0) =6 MCD(12,6) =6 MCD(18,12) =6 MCD(30,18) =6 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1  

DIMOSTRAZIONE PER INDUZIONE DELLA CORRETTEZZA DELL’ALGORTIMO RICORSIVO PER IL MCD caso base Poniamo MCD(M,0)=M passo induttivo Dobbiamo ora dimostrare che MCD(M’,N’)=MCD(N, M MOD N) Supponiamo MCD(M’,N’)=X essendo N’=M MOD N questo implica per definizione che M=kN+N’ dove k è un intero allora M’=hX e N’=zX dove h e z sono interi ma N’=zX allora M=kN+zX inoltre N=M’=hX quindi M=khX+zX=(kh+z)X=wX essendo allora sia M che N divisibili per X questo è il MCD(M,N)

ALTRI ESEMPI Supponiamo di avere 3 lettere a b c. Vogliamo sapere quante permutazioni si possono fare con questi 3 caratteri. - ci sono 3 maniere per scegliere quale lettera mettere in terza posizione (genericamente n) abc acb cba - per ognuna delle 3 scelte precedenti ci sono 2 maniere diverse per scegliere la lettera da mettere in seconda posizione in totale 3*2 (genericamente n*(n-1)) abc bac acb cab cba bca - per ognuna delle 6 scelte precedenti c’è 1 sola maniera per scegliere la lettere da mettere in prima posizione in totale 3*2*1 (genericamente n*(n-1)…..*1)

Si definisce FATTORIALE di un numero N il prodotto di tutti i numeri da 0 a N come di seguito definito: Di seguito sono mostrati gli algoritmi e relativi codici iterativi e ricorsivi

double fattorialeIterativo(int Num) { int fatt=1; for (int j=1;j<=Num;j++) fatt=j*fatt; return fatt; } double fattorialeRicorsivo(int Num) { if (Num==0) return 1; else return Num*fattoriale(Num-1); }

La completezza dipende dal dominio su cui si definisce l’algoritmo. Un algoritmo ricorsivo deve essere completo, deve cioè sempre esistere una soluzione qualunque sia l’input. La completezza dipende dal dominio su cui si definisce l’algoritmo. Esempio: PotenzaN se definito sugli interi non è completo perché non funziona per gli interi negativi (infatti N-1 per N negativo non raggiunge mai lo 0). Diventa completo se il domino di definizione è quello dei numeri interi positivi. double PotenzaN(double Xre,int N) { if (N==0) return 1; else return Xre*PotenzaN(Xre,N-1); }

Ciò accade quando non si raggiunge mai il caso base. Dall’esempio precedente si ricava che nel caso di cattiva definizione dell’algoritmo ricorsivo sia in termini di caso base che di chiamata ricorsiva si genera uno Stack Infinito. Ciò accade quando non si raggiunge mai il caso base. Infatti nel caso dell’algoritmo per il calcolo delle potenze di N se N è negativo sottraendo ad esso 1 ad ogni chiamata ricorsiva non raggiugeremmo mai il caso base previsto per N=0. double PotenzaN(double Xre,int N) { if (N==0) return 1; else return Xre*PotenzaN(Xre,N-1); }