(* leggi non e' tail recursive: al ritorno dalla ricorsione si deve ancora aggiungere 1 al risultato *)

Documenti analoghi
La principale modalità di calcolo è l applicazione di funzioni

Programmazione Ricorsione in coda

Un algoritmo realizza una relazione funzionale tra i valori di input e quelli di output

Tecniche per risolvere problemi: riduzione a sottoproblemi più semplici. Ricorsione

Definizioni ricorsive

Introduzione a Matlab

PREPARAZIONE PER SECONDA PROVA IN ITINERE Esercizio 1 SULLA MODELLAZIONE DEI DATI

Mini-Corso di Informatica

Corso di Fondamenti di Informatica. La ricorsione

Esercitazione 4. Comandi iterativi for, while, do-while

Introduzione al MATLAB c Parte 3 Script e function

Programmazione Ricorsione

print((math.floor(1345/10)%10); print (Math.floor(1345/100)%10); Le funzioni in JavaScript

Semantica dei programmi. La semantica dei programmi è la caratterizzazione matematica dei possibili comportamenti di un programma.

Programmazione di INFORMATICA e Laboratorio

Diagrammi di flusso. Un metodo per rappresentare graficamente gli algoritmi. sotto programma. Input/ Output. Start. predicato Elaborazione Stop

Laboratorio di Python

Tempo e spazio di calcolo (continua)

Strutture di Controllo

PROGRAMMAZIONE STRUTTURATA

Architetture dei Calcolatori

Introduzione a Visual Basic Lezione 2 Cicli e anomalie

osservazione: 1 MCD(m,n) min(m,n) = si provano i numeri compresi tra 1 e min(m,n) conviene iniziare da min(m,n) e scendere verso 1

UNIVERSITÀ DEGLI STUDI DI PAVIA FACOLTÀ DI INGEGNERIA. Matlab: esempi ed esercizi

Dall algoritmo al programma

Corso di Fondamenti di Informatica Classi di istruzioni 2

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1

Esempio : i numeri di Fibonacci

Capitolo 19. Ricorsione

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

INFORMATICA GENERALE Prof. Alberto Postiglione Dipartimento Scienze della Comunicazione Università degli Studi di Salerno

Istruzioni iterative. Istruzioni iterative

Informatica/ Ing. Meccanica/ Prof. Verdicchio/ 14/02/2012 / Foglio delle domande / VERSIONE 1

Ricorsione. Unità 5. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Istruzioni condizionali di diramazione in Fortran 90

Fondamenti di Programmazione

Fondamenti dell Informatica Ricorsione e Iterazione Simona Ronchi Della Rocca (dal testo: Kfoury, Moll and Arbib, cap.5.2)

Programmazione Funzionale

Esercitazione 3. Espressioni booleane I comandi if-else e while

Algoritmi e basi del C Struttura di un programma

Array in Fortran 90. Ing. Luca De Santis. Anno accademico 2006/2007. DIS - Dipartimento di informatica e sistemistica

Costrutti condizionali e iterativi

CORSO DI LAUREA IN INGEGNERIA ELETTRICA

Shell: variabili di sistema. Per visualizzare il valore di tutte le variabili d ambiente si usa il comando set

Informatica/ Ing. Meccanica/ Prof. Verdicchio/ 13/09/2013/ Foglio delle domande/versione 1

Programma del corso. Elementi di Programmazione. Introduzione agli algoritmi. Rappresentazione delle Informazioni. Reti di Calcolatori

Fondamenti di Informatica

Parte 2. Ricorsione. [M.C.Escher Drawing hands, 1948] - AA. 2012/13 2.1

Metodi di Analisi dei Dati Sperimentali. AA 2009/2010 Pier Luca Maffettone. Elementi di Matlab

Descrizione di un algoritmo

INFORMATICA DI BASE Linguaggio C Prof. Andrea Borghesan

Rappresentazione con i diagrammi di flusso (Flow - chart)

4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt);

let quorem pair = ((fst pair)/(snd pair), (fst pair) mod (snd pair))

Esercizi su programmazione ricorsiva 1. Pericle Perazzo 23 marzo 2012

Pile Le pile: specifiche e realizzazioni attraverso rappresentazioni sequenziali e collegate. Pile e procedure ricorsive

Introduzione all ambiente MATLAB. Richiami II. Calcolo Numerico - A.A. 2008/09

Modularizzazione del software

Alberi Binari di Ricerca

Esercitazione. Ricorsione. May 31, Esercizi presi dal libro di Rosen

1 Esercizi di Matlab. L operatore : permette di estrarre sottomatrici da una matrice assegnata. Vediamo alcuni esempi.

FUNZIONI RICORSIVE PROGRAMMAZIONE RICORSIVA: Esempi di problemi ricorsivi:

Tipici tempi di esecuzione. Martedì 7 ottobre 2014

ARRAY E STRINGHE. ESERCIZIO 2 Scrivere un programma che calcola il numero di doppie e di dittonghi (2 vocali vicine) presenti in una stringa.

MINIMANUALE VBA PER CREARE MACRO NEI FOGLI EXCEL

DEC PDP8, III Generazione, '65-'75

Cos è un algoritmo. Si dice algoritmo la descrizione di un metodo di soluzione di un problema che sia

La ricorsione. Ver Claudio Fornaro - Corso di programmazione in C

Stringhe e allocazione dinamica della memoria

6 - Blocchi e cicli. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Sviluppare un programma in FORTRAN

Istruzioni di ciclo. Unità 4. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi

Università degli Studi di Salerno. Corso di Laurea in Scienze della Comunicazione Informatica generale (matr. Dispari) Docente: Angela Peduto

Corso di Informatica di Base

Le Funzioni e la Ricorsione

Iterazione determinata e indeterminata

Elaborazione dell informazione

Sistemi Operativi Teledidattico

Algoritmi e dintorni: La radice quadrata Prof. Ettore Limoli. Formule iterative

Le etichette nei programmi. Istruzioni di branch: beq. Istruzioni di branch: bne. Istruzioni di jump: j

JavaScript Core Language. Prof. Francesco Accarino IIS Atiero Spinelli Sesto San Giovanni via leopardi 132

in termini informali: un algoritmo è una sequenza ordinata di operazioni che risolve un problema specifico

Laboratorio di Algoritmi e Strutture Dati

DIPARTIMENTO DI ELETTRONICA, INFORMAZIONE E BIOINGEGNERIA. INFORMATICA B Ingegneria Elettrica. La ricorsione

Processore Danilo Dessì. Architettura degli Elaboratori.

Linguaggio C - le strutture di controllo: sequenza, selezione, iterazione

Diagrammi a blocchi 1

Esercitazione 2. Corso di Fondamenti di Informatica

Ricorsione. La ricorsione consiste nella possibilità di definire una funzione in termini di se stessa

Breve guida al linguaggio FORTRAN 77

Formalismi per la descrizione di algoritmi

Laboratorio di programmazione

19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Esercitazioni di Fondamenti Informatica - Modulo A 1

Le Strutture di controllo Del Linguaggio C. Prof. Francesco Accarino IIS Altiero Spinelli Sesto San Giovanni

Esercizio 2 (punti 7) Dato il seguente programma C: #include <stdio.h> int swap(int * nome, int length);

Corso di Fondamenti di Informatica

Problemi, algoritmi e oggetti

LABORATORIO DI INFORMATICA

Transcript:

(* come si implementa un ciclo? (* funzioni di put e output http://caml.ria.fr/pub/docs/manual-ocaml/libref/pervasives.html Standard put e standard output: val prt_strg : strg -> unit val prt_t : t -> unit... val read_le : unit -> strg val read_t : unit -> t... sequenze di comandi (* ciclo: t -> t -> unit ciclo n m: stampa gli teri da n a m (estremi clusi) let rec ciclo n m = if n>m then () else (prt_t n; (* sequenza di comandi prt_newle(); ciclo (n+1) m) (* ciclo e' "tail recursive": al ritorno dalla chiamata ricorsiva non si deve fare nulla (* ciclo2: t -> unit ciclo2 n: stampa degli teri da 0 a n let ciclo2 = ciclo 0 (* leggi: unit -> t legge una sequenza di lee termata da "." e ne riporta il numero let rec leggi () = let s = read_le () if s="." then 0 else 1 + leggi() (* leggi non e' tail recursive: al ritorno dalla ricorsione si deve ancora aggiungere 1 al risultato (* somma: unit -> t legge una sequenza di teri termata da "." e riporta la somma dei numeri letti let rec somma () = let s = read_le () if s="." then 0 else (t_of_strg s) + somma() (* somma non e' tail recursive (* uso "sporco" delle eccezioni let rec somma2 () = try let n = t_of_strg (read_le()) n + somma2() with _ -> 0 (*strglen: strg -> t (* lunghezza di una strga = Strg.length let strglen s = (* aux: t -> t aux i = numero di caratteri s che vanno dalla posizione i

alla fe della strga. implementa un ciclo. E' tail recursive let rec aux i = try let _ = s.[i] (* serve solo per verificare se s.[i] esiste aux (i+1) with _ -> i (* izializzazione del ciclo: izialmente, i=0 aux 0 (* loop: unit -> t * t riporta numero e somma degli teri letti let s = read_le() if s="." (* termato? then (0,0) (* nessun numero letto, somma 0 else (* strga rappresenta un t, leggi gli altri numeri let (tot,somma) = loop() (tot+1,somma+(t_of_strg s)) (* oppure try let n = t_of_strg(read_le()) let (tot,somma) = loop() (tot+1,somma+n) with _ -> (0,0) (* loop non e' tail recursive (* General put/output functions: http://caml.ria.fr/pub/docs/manual-ocaml/libref/pervasives.html val open_out : strg -> out_channel val output_strg : out_channel -> strg -> unit val close_out : out_channel -> unit val open_ : strg -> _channel val put_le : _channel -> strg val close_ : _channel -> unit (* obiettivo: leggere da file una sequenza di numeri (* teri, termata dalla strga ".", scrivere il numero di teri (* letti, la loro somma, e la media (* media: strg -> unit (* la strga e` il nome del file let rec media file = (* apertura del canale di put let chan = open_ file (* "ciclo" di lettura dei numeri (* riporta numero di teri letti e loro somma (* loop: unit -> t * t let strga = put_le chan (* lettura da file if strga = "." then (* sequenza di comandi beg close_ chan; (* chiusura del canale di put (0,0) end else let (n,somma) = loop ()

(n+1, somma + (t_of_strg strga)) let (n,somma) = loop () (* sequenza di comandi prt_strg ("Letti "^(strg_of_t n)^ " teri\nsomma: "^(strg_of_t somma)^ "\nmedia: "^ (strg_of_float ((float_of_t somma)/.(float_of_t n))) ^"\n") (* niente overloadg (* ----------------------------- (* processi ricorsivi e iterativi let rec fact = function 0 -> 1 n -> n * fact(n-1) (* la funzione non e' tail recursive: implementa un processo ricorsivo (* fact 3 ==> 3 * fact 2 ==> 3 * (2 * fact 1) ==> 3 * (2 * (1 * fact 0)) ==> 3 * (2 * (1 * 1)) ==> 3 * (2 * 1) ==> 3 * 2 ==> 6 Ma il prodotto e' associativo, qudi: 3 * (2 * fact 1) = (3 * 2) * fact 1 e: fact 3 = 3 * fact 2 = (3 * 2) * fact 1 = (6 * 1) * fact 0 = 6 * 1 = 6 Non c'e' bisogno di aspettare il risultato delle chiamate ricorsive, possiamo eseguire subito il calcolo 3*2 e conservarlo un "accumulatore" (o risultato parziale) ==> algoritmo iterativo let rec fact' n = (* aux: t -> t -> t il primo argomento e' il "risultato parziale" let rec aux f = function 0 -> f (* il "ciclo" terma n -> aux (f*n) (n-1) aux 1 n (* il ciclo e' implementato mediante un costrutto ricorsivo. Uso di una funzione ausiliaria che ha un parametro piu', l'accumulatore: i suoi argomenti sono le variabili che vengono "modificate" nel ciclo. La funzione prcipale richiama quella ausiliaria "izializzando" le variabili del ciclo (* il processo e' iterativo: fact' 3 = aux 3 1 = aux(2,3) = aux(1,6) = aux(0,6) = 6 Dopo aver raccolto il risultato della chiamata ricorsiva, non si deve fare nulla.

(* Ma cosa calcola aux (specifica dichiarativa)? (* Un processo ricorsivo: - esegue calcoli al ritorno dalla ricorsione - usa spazio proporzionale alla "dimensione" dell'put. In un processo iterativo: - il risultato parziale viene conservato un accumulatore; - dopo aver faccolto il risultato della chiamata ricorsiva non si deve fare nulla - l'ultima chiamata puo' riportare il suo risultato direttamente alla prima (* ciclo implementa un processo iterativo o ricorsivo? leggi, somma, strglen, loop? (* leggi_it: unit -> t legge una sequenza di lee termata da "." e ne riporta il numero let leggi_it () = let rec aux n = (* n = numero di righe lette fora let s = read_le() if s="." then n (* n e non 0 else aux (n+1) (* cremento del risultato parziale (* i calcoli sono eseguiti PRIMA della chiamata ricorsiva aux 0 (* izializzazione del risultato parziale (* somma_it: unit -> t legge una sequenza di teri termata da "." e riporta la somma dei numeri letti let somma_it () = let rec aux tot = (* tot = somma dei numeri letti fora let s = read_le() if s="." then tot (* tot e non 0 else aux (tot + (t_of_strg s)) (* cremento del risultato parziale aux 0 (* izializzazione del risultato parziale (* loop_it: unit -> t * t riporta numero e somma degli teri letti let loop_it () = (* aux: t -> t -> t * t let rec aux tot somma = (* due "accumulatori" let s = read_le () if s="." then (tot,somma) (* e non (0,0) else aux (tot+1) (somma + (t_of_strg s)) (* cremento degli "accumulatori" aux 0 0 (* uso di loop iterativo media (* media_it: strg -> unit (* media_it s = legge dal file di nome s una sequenza di numeri (* teri, termata dalla strga ".", e stampa il numero di teri (* letti, la loro somma, e la media let rec media_it file = let chan = open_ file let rec loop tot somma = let s = put_le chan if s = "." then beg close_ chan; (tot,somma) end

else loop (tot+1) (somma + (t_of_strg s)) let (n,somma) = loop 0 0 (* <=== izializzazione prt_strg ("Letti "^(strg_of_t n)^ " teri\nsomma: "^(strg_of_t somma)^ "\nmedia: "^ (strg_of_float ((float_of_t somma)/.(float_of_t n))) ^"\n")