• Non ci sono risultati.

Esercitazione IV IEIM

N/A
N/A
Protected

Academic year: 2021

Condividi "Esercitazione IV IEIM"

Copied!
58
0
0

Testo completo

(1)

IEIM

Esercitazione IV

2014-2015

Alessandro A. Nacci

alessandro.nacci@polimi.it - alessandronacci.it

(2)

2

(3)

RICORSIONE

(4)

Divide et impera

Metodo di approccio ai problemi che consiste nel dividere il problema dato in problemi più semplici

I risultati ottenuti risolvendo i problemi più semplici vengono combinati insieme per

costituire la soluzione del problema originale

Generalmente, quando la semplificazione del problema consiste essenzialmente nella

semplificazione dei DATI da elaborare (ad es. la riduzione della dimensione del vettore da

elaborare), si può pensare ad una soluzione ricorsiva

4

(5)

La ricorsione (1)

Una funzione è detta ricorsiva se chiama se stessa

Se due funzioni si chiamano l’un l’altra, sono dette mutuamente ricorsive

La funzione ricorsiva sa risolvere direttamente solo casi particolari di un problema detti casi di base: se viene invocata passandole dei dati che

costituiscono uno dei casi di base, allora restituisce un risultato

Se invece viene chiamata passandole dei dati che NON costituiscono uno dei casi di base, allora chiama se stessa (passo ricorsivo) passando dei

(6)

La ricorsione (II)

Ad ogni chiamata si semplificano/riducono i dati, così ad un certo punto si arriva ad uno dei casi di base

Quando la funzione chiama se stessa, sospende la sua esecuzione per eseguire la nuova chiamata

L’esecuzione riprende quando la chiamata interna a se stessa termina

La sequenza di chiamate ricorsive termina quando quella più interna (annidata) incontra uno dei casi di base

Ogni chiamata alloca sullo stack (in stack frame diversi) nuove istanze dei parametri e delle variabili locali (non static)

6

(7)

Esempio: il fattoriale

(8)

Esempio: il fattoriale - passo per passo

8

(9)

Ricorsione - Esercizio 1

Scrivere una funziona ricorsiva che calcoli ricorsivamente la somma di tutti i numeri compresi tra 0 ed x

Il prototipo della funzione è: int ric(int x)

(10)

Ricorsione - Esercizio 1

Scrivere una funziona ricorsiva che calcoli ricorsivamente la somma di tutti i numeri compresi tra 0 ed x

Il prototipo della funzione è: int ric(int x)

9

(11)

Ricorsione - Esercizio 1I

Scrivere le versioni ricorsiva ed iterativa di una funziona che

calcoli il seguente valore

(12)

Ricorsione - Esercizio 1I

Scrivere le versioni ricorsiva ed iterativa di una funziona che

calcoli il seguente valore

10

(13)

Ricorsione - Esercizio 1I

Scrivere le versioni ricorsiva ed iterativa di una funziona che

calcoli il seguente valore

(14)

Ricorsione - Esercizio 1I

Scrivere le versioni ricorsiva ed iterativa di una funziona che

calcoli il seguente valore

10

(15)

Qualche considerazione

L’apertura delle chiamate ricorsive semplifica il problema, ma non calcola ancora nulla

Il valore restituito dalle funzioni viene utilizzato per calcolare il valore finale man mano che si

chiudono le chiamate ricorsive: ogni chiamata genera valori intermedi a partire dalla fine

Nella ricorsione vera e propria non c’è un mero passaggio di un risultato calcolato nella chiamata più interna a quelle più esterne, ossia le return non si limitano a passare indietro invariato un valore, ma c’è un’elaborazione intermedia

(16)

Quando utilizzare la ricorsione

12

(17)

Quando utilizzare la ricorsione

(18)

Ricorsione - Esercizio III

Analizzare il comportamento della seguente funzione ricorsiva mostrando l’andamento

delle variabili, considerando i seguenti input:

funzione(231,0)

Dire quale funzione espleta

14

#include <stdio.h>

#define DIMENSIONE 10

int mia_funzione(int num, int part) { if (num == 0)

return part;

else {

return mia_funzione(num/10, part*10 + num%10);

} }

int main() {

int a = reverse2(21,0);

printf("%d\n",a);

}

(19)

Ricorsione - Esercizio III - Soluzione

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

num  =  231 port  =  0

~ STEP  =  0

(20)

Ricorsione - Esercizio III - Soluzione

16

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

}

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  0

~ STEP  =  1

(21)

Ricorsione - Esercizio III - Soluzione

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  0

~ STEP  =  1

num  =  2 port  =  0

~ STEP  =  2

(22)

Ricorsione - Esercizio III - Soluzione

18

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

}

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  1

~ STEP  =  1

num  =  2

port  =  10+3  =  13

~ STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

~ STEP  =  3

(23)

Ricorsione - Esercizio III - Soluzione

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  1

~ STEP  =  1

num  =  2

port  =  10+3  =  13

~ STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

132 STEP  =  3

(24)

Ricorsione - Esercizio III - Soluzione

20

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

}

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  1

~ STEP  =  1

num  =  2

port  =  10+3  =  13

132 STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

132 STEP  =  3

(25)

Ricorsione - Esercizio III - Soluzione

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  1

~ STEP  =  1

num  =  2

port  =  10+3  =  13

132 STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

132 STEP  =  3

(26)

Ricorsione - Esercizio III - Soluzione

22

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

}

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  1

132 STEP  =  1

num  =  2

port  =  10+3  =  13

132 STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

132 STEP  =  3

(27)

Ricorsione - Esercizio III - Soluzione

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

num  =  231 port  =  0

~ STEP  =  0

num  =  23 port  =  1

132 STEP  =  1

num  =  2

port  =  10+3  =  13

132 STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

132 STEP  =  3

(28)

Ricorsione - Esercizio III - Soluzione

24

int funzione (int num, int port) {

if (num == 0) return port;

else

return funzione (num/10, port*10 + num%10);

}

num  =  231 port  =  0

132 STEP  =  0

num  =  23 port  =  1

132 STEP  =  1

num  =  2

port  =  10+3  =  13

132 STEP  =  2

num  =  0

port  =  13  *10  +  2  =  132

132 STEP  =  3

(29)

Un esercizio complesso:

Albero genealogico

(30)

L’albero genealogico

Scrivere un programma C che sia in grado di rappresentare e gestire un albero genealogico

26

In particolare, vogliamo poter fare:

-

Creare una persona

-

Rappresentare di una popolazione

-

Aggiungere figli ad una persona

-

Elencare i figli e i nipoti dato un antenato

(31)

Una famosa struttura dati: l’albero

P0

P1 P2 P3

P4 P5

(32)

Una famosa struttura dati: l’albero

27

P0

P1 P2 P3

P4 P5

ogni cerchio si chiama “nodo”

(33)

Una famosa struttura dati: l’albero

P0

P1 P2 P3

P4 P5

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

(34)

Una famosa struttura dati: l’albero

27

P0

P1 P2 P3

P4 P5

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

(35)

Una famosa struttura dati: l’albero

P0

P1 P2 P3

P4 P5

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

PADRE

FIGLIO

(36)

Una famosa struttura dati: l’albero

27

P0

P1 P2 P3

P4 P5

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

PADRE

FIGLIO PADRE

FIGLIO

(37)

Una famosa struttura dati: l’albero

P0

P1 P2 P3

P4 P5

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

PADRE

FIGLIO PADRE

FIGLIO

PADRE

FIGLIO

(38)

Una famosa struttura dati: l’albero

27

P0

P1 P2 P3

P4 P5

RADICE

FOGLIA FOGLIA

FOGLIA FOGLIA

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

PADRE

FIGLIO PADRE

FIGLIO

PADRE

FIGLIO

(39)

Una famosa struttura dati: l’albero

P0

P1 P2 P3

P4 P5

RADICE

FOGLIA FOGLIA

FOGLIA FOGLIA

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

PADRE

FIGLIO PADRE

FIGLIO

PADRE

FIGLIO

(40)

Una famosa struttura dati: l’albero

27

P0

P1 P2 P3

P4 P5

Può essere utile per rappresentare un albero genealogico?

RADICE

FOGLIA FOGLIA

FOGLIA FOGLIA

ogni cerchio si chiama “nodo”

PADRE

FIGLIO

PADRE

FIGLI

PADRE

FIGLIO PADRE

FIGLIO

PADRE

FIGLIO

OVVIAMENTE SI

(41)

OGNI NODO DELL’ALBERO SARA’ PER NOI UNA PERSONA

==

P

(42)

Una Persona

SESSO

NOME

ETA?

CHI SONO I GENITORI?

CHI SONO I FIGLI?

QUANTI FIGLI?

29

(43)

Una Popolazione

Una popolazione è rappresentata da un insieme di persone

Ogni persona ha un suo indice (numero univoco di identificazione)

Esiste un numero di persone della

1 2 3 4 5 6 7

(44)

Una Persona nella popolazione

SESSO

NOME

ETA?

CHI SONO I GENITORI?

CHI SONO I FIGLI?

QUANTI FIGLI?

cardinalità 31

1 2 3 4 5 6 7

Li rappresentiamo con l’indice della persona nella popolazione

(45)

Persona e Popolazione (codice C)

(46)

Persona e Popolazione (codice C)

32

(47)

Persona e Popolazione (codice C)

(48)

Creazione di una persona

33

(49)

Creazione di una persona

(50)

Aggiunta persona alla popolazione

34

(51)

Aggiunta persona alla popolazione

(52)

Aggiunta di un figlio

35

(53)

Aggiunta di un figlio

(54)

Funzioni di stampa a schermo

36

(55)

Funzioni di stampa a schermo

(56)

Funzioni di stampa a schermo

36

(57)
(58)

38

Tutte il materiale sarà disponibile sul mio sito internet!

alessandronacci.it

Riferimenti

Documenti correlati

Per ipotesi induttiva, cio` e, a meno di riordinare tali vettori, possiamo supporre che {v

Osservazione 0.4 La nostra definizione privilegia l’equivalenza algebrica delle equazioni sull’equivalenza geometrica degli insiemi: se esiste (a sistema di coordinate

Da allora, i monaci del tempio si alternano per spostare i dischi dal piolo originario ad un altro piolo, seguendo le rigide regole di Brahma: i dischi vanno ma- neggiati uno

sulle calcolatrici scientifiche sono presenti i tasti lg e ln che consentono di calcolare i logaritmi in base 10 e in

Istituzioni di Matematiche II

– Si parla di ricorsionelineare quando vi è solo una chiamata ricorsiva all'interno della funzione, e di ricorsione non lineare nel caso in cui le chiamate ricorsive siano più di una.

  Individuare, in un gruppo di palline l’unica pallina di peso maggiore delle altre facendo uso di una bilancia “a basculla” (Per semplicità: il numero di palline sia una

• Costruire una rappresentazione discreta della funzione sin(x) nei valori nodali definiti sull’intervallo discretizzato [0,pi,passo]; passo=0.1.. • Calcolare