La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

CAPITOLO 10.

Presentazioni simili


Presentazione sul tema: "CAPITOLO 10."— Transcript della presentazione:

1 CAPITOLO 10

2 ARRAY CON SUB-RANGE DIVERSI DAGLI INTERI
1 2 3 . 100 Indice  In Pascal si può usare come sub-range un qualunque ordinal type Un ordinal type, cioè un tipo per il quale è noto il successore e il predecessore di ogni valore escluso il primo e l’ultimo.

3 Contare il numero di volte che ciascuna lettera dell’alfabeto
Problema Contare il numero di volte che ciascuna lettera dell’alfabeto compare in un preassegnato testo e calcolare la percentuale della ricorrenza di ciascuna lettera rispetto al totale. Sia C:\TP\ESEMPI\TESTO.TXT il file di testo da analizzare. Output Introduci il Nome del file: C:\TP\ESEMPI\TESTO.TXT Lettera Occorrenze Percentuale A B Z

4 ArrayContatore = ARRAY[‘a’..’z’] OF integer; VAR
b c . z Indice  ContaLettere TYPE ArrayContatore = ARRAY[‘a’..’z’] OF integer; VAR ContaLettere: ArrayContatore; N.B. Il programma deve contare sia le lettere minuscole che le maiuscole. Poiché di solito le minuscole sono più frequenti abbiamo definito il sub-range in termini di minuscole mentre opereremo la conversione maiuscola-minuscola nel caso che appaiano lettere maiuscole.

5 Pseudo-codice LeggiNomeFile(UnFile) reset(UnFile) AzzeraContatori(ContaLettere) ContaOccorrenze(UnFile,ContaLettere) close(UnFile) MostraOccorrenze(NomeFile,ContaLettere) Cerchiamo solo i caratteri IN[‘a’..’z’] o IN[‘A’..’Z’] quindi se leggiamo eoln, non appartenendo esso ai sub-range indicati non viene preso in esame, per cui non è necessario il controllo sull’eoln. E’ invece obbligatorio il controllo sull’eof.

6 ContaOccorrenze(UnFile,ContaLettere)
Pseudo-codice WHILE NOT eof(UnFile) DO read(UnFile,Carattere) IF Carattere è una lettera THEN aggiungi 1 all’elemento corrispondente in ContaLettere

7 PROGRAM ContaLeLettere(input,output, UnFile);
{conta e mostra le occorrenze di tutte le lettere presenti in un file testo} CONST LunMass=30; TYPE ArrayContatore=ARRAY['a'..'z'] OF integer; StringaNome=STRING[LunMass]; VAR Unfile : text; {variabile di file da cui sono contate le lettere} ContaLettere: ArrayContatore; {memorizza le occorrenze} NomeFile: StringaNome; {directory e nome file testo} LeggiNomeFile(UnFile) reset(UnFile) AzzeraContatori(ContaLettere) ContaOccorrenze(UnFile,ContaLettere) close(UnFile) MostraOccorrenze(NomeFile,ContaLettere) PROCEDURE LeggiNomeFile(VAR NomeFile: StringaNome; VAR UnFile: text); BEGIN write(' Dammi il nome del file da elaborare: '); readln(NomeFile); assign(UnFile, NomeFile) END; PROCEDURE AzzeraContatori(VAR ContaLettere: ArrayContatore); VAR IndiceLettera: ‘a’..’z’; BEGIN FOR IndiceLettera:=‘a’ TO ‘z’ DO ContaLettere[IndiceLettera]:=0; END;

8 PROCEDURE ContaOccorrenze(VAR ContaLettere : ArrayContatore;
LeggiNomeFile(UnFile) reset(UnFile) AzzeraContatori(ContaLettere) ContaOccorrenze(UnFile,ContaLettere) close(UnFile) MostraOccorrenze(NomeFile,ContaLettere) PROCEDURE ContaOccorrenze(VAR ContaLettere : ArrayContatore; VAR UnFile: text); VAR Scambio: integer; Carattere: char; BEGIN Scambio:= ord('a')-ord('A'); WHILE NOT eof(UnFile) DO read(UnFile,Carattere); IF Carattere IN['A'..'Z'] THEN Carattere:=chr(ord(Carattere)+Scambio); IF Carattere IN['a'..'z'] THEN ContaLettere[Carattere]:=ContaLettere[Carattere]+1 END END;

9 FOR IndiceLettera:= 'a' TO 'z' DO
PROCEDURE MostraOccorrenze(NomeFile: StringaNome; ContaLettere : ArrayContatore); VAR IndiceLettera: 'a'..'z'; MostraLettera: 'A'..'Z'; Scambio, SommaLettere: integer; BEGIN Scambio:=ord('A')-ord('a'); write('Le occorrenze delle lettere nel file '); writeln(NomeFile, ' sono: '); writeln; SommaLettere:=0; {serve per il calcolo delle frequenze } FOR IndiceLettera:= 'a' TO 'z' DO SommaLettere:=SommaLettere+ContaLettere[IndiceLettera]; END; MostraLettera:=chr(ord(IndiceLettera) + Scambio); {cambio min/maiusc} write(' ':24,MostraLettera,'''s -- '); writeln(ContaLettere[IndiceLettera]:1,' % ', (ContaLettere[IndiceLettera] / SommaLettere)*100:10:2); LeggiNomeFile(UnFile) reset(UnFile) AzzeraContatori(ContaLettere) ContaOccorrenze(UnFile,ContaLettere) close(UnFile) MostraOccorrenze(NomeFile,ContaLettere)

10 { ******************** BODY ******************}
BEGIN LeggiNomeFile(NomeFile,UnFile); reset(UnFile); AzzeraContatori(ContaLettere); ContaOccorrenze(ContaLettere, UnFile); close(UnFile); MostraOccorrenze(NomeFile, ContaLettere); readln END.

11 ESERCIZIO Gioco della TOMBOLA Dati i 90 numeri della Tombola effettuare una estrazione completa di tutti i numeri con un generatore random. Impedire che venga estratto due volte lo stesso numero.

12 LA TOMBOLA 2 ... 30 90 1 NumeroRandom 1..90  30
[0] [1] [..] [30] [90] NumeroRandom  30 NumeroEstratto Interi[30]  30 2 ... 90 89 1 [0] [1] [..] [30] [89] [90] NumeroRandom  2 NumeroEstratto Interi[2]  2 89 ... 90 1 [0] [1] [..] [30] [89] [90] NumeroRandom  30 NumeroEstratto Interi[2]  90 89 ... 88 90 1 [0] [1] [..] [30] [89] [90]

13 ESEMPIO 10.2 Si vuole simulare l’attività del cambio di monete. A partire dal valore giornaliero dei valori di cambio, data una certa cifra in una moneta corrente si chiede l’equivalente in un’altra moneta. Supponiamo che le monete trattate siano: Lire, Dollaro, Rublo,Yen, Sterlina, Franco Svizzero.

14 Il dialogo che vogliamo si svolga tra utente e macchina è del tipo:
Buongiorno. Dammi i cambi della Lira di oggi: Dollaro: 1909 Rublo: Sterlina: 3097 Yen: 18.64 Franco Svizzero: 1210 Grazie.

15 Abbiamo finito per oggi? (S/N) N
Moneta da convertire: Yen Moneta in cui convertire: Sterlina Cambio da Yen a Sterlina. Valore da cambiare: 1000 1000 Yen si convertono in Sterline ………………………. Batti un tasto per effettuare cambi. Abbiamo finito per oggi? (S/N) S

16 Pseudo-codice DammiCambi(DaLireA) REPEAT DammiMonete(DaMoneta, NuovaMoneta) Cambia(DalireA, AmmontareDaCamb, AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta, NuovaMoneta, AmmontareDaCamb,AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s']

17 RAPPRESENTAZIONE GRAFICA
Istruzioni DammiCambi Ripeti finchè la Risposta è NO DammiMonete Cambia MostraQuadroRiepilogativo DaLireA DaMoneta NuovaMoneta AmmontareDaCamb AmmontareCambiato Valido Nome Moneta

18 STRUTTURA DATI 1000 1909 989.99 3097 1210 18.64 Indice 
ArrayConversione 1000 Lira 1909 Dollaro Rapporto di conversione = valore moneta richiesta valore moneta offerta 989.99 Rublo 3097 Sterlina 1210 Franco Svizzero 18.64 Yen

19 Usiamo il TYPE enumerativo
TipoMoneta=(Nessuno, Lira, Dollaro, Rublo, Sterlina, FrancoSvizzero, Yen) ArrayConversione=ARRAY[Lira..Yen] of REAL; VAR DaLireA: ArrayConversione DaMoneta, AMoneta: TipoMoneta

20 PROGRAM SimulazioneCambiBancari(input,output); { } TYPE
{ } TYPE TipoMoneta=(Nessuno, Lira, Dollaro, Rublo, Sterlina, FrancoSvizzero, Yen) ArrayConversione=ARRAY[Lira..Yen] of real; VAR DaLireA: ArrayConversione; DaMoneta, NuovaMoneta: TipoMoneta; AmmontareDaCamb, AmmontareCambiato : real; Risposta: char; ………………………………………………………………………………………... { ******************* BODY *********************** } BEGIN Istruzioni; DammiCambi(DaLireA); REPEAT DammiMonete(DaMoneta, NuovaMoneta); Cambia(DalireA, AmmontareDaCamb,AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta,NuovaMoneta,AmmontareDaCamb, AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s'] END.

21 DammiCambi Pseudo-codice DaLireA[Lire]  1.000
BEGIN Istruzioni; DammiCambi(DaLireA); REPEAT DammiMonete(DaMoneta, NuovaMoneta); Cambia(DalireA,AmmontareDaCamb,AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta,NuovaMoneta, AmmontareDaCamb,AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s'] END. DammiCambi Pseudo-codice DaLireA[Lire]  1.000 FOR Moneta  Dollaro TO Yen DO MostraCambi readln(DaLireA [Moneta] ) PROCEDURE DammiCambi(VAR DaLireA1: Tipo ArrayConversione); { } VAR Moneta: TipoMoneta; BEGIN DaLireA1[Lire]:=1000; writeln(‘ Salve! Dammi i rapporti di cambio di oggi: ‘); FOR Moneta:=Dollaro TO Yen DO write (‘Lire / ‘);MostraCambio(Moneta); write(‘: ‘); readln(DaLireA1[Moneta]) END; writeln(‘ Grazie! Ciao ‘);

22 DammiMonete Pseudo-codice REPEAT introduci SiglaMoneta UNTIL Valido(SiglaMoneta) DaMoneta  Nome(SiglaMoneta) NuovaMoneta  Nome(SiglaMoneta) mostra i valori delle monete

23 FUNCTION Valido(SiglaMoneta1: char): boolean;
BEGIN Valido:=SiglaMoneta1 IN [‘L’,’D’,’R’,’S’,’Y’] END; FUNCTION Nome(SiglaMoneta1: char): TipoMoneta; { } BEGIN CASE SiglaMoneta1 OF ‘E’: Nome:=Lira; ’D’: Nome:= Dollaro; ’R’: Nome:= Rublo; ’S’: Nome:= FrancoSvizzero; ’Y’: Nome:= Yen END {CASE} END;

24 PROCEDURE DammiMonete(VAR DaMon, NuovaMon: TipoMoneta); VAR
Moneta: char; BEGIN REPEAT write('Cambio da: '); readln(Moneta); UNTIL Valido(Moneta); DaMon:=Nome(Moneta); write('A: '); NuovaMon:=Nome(Moneta) END; BEGIN Istruzioni; DammiCambi(DaLireA); REPEAT DammiMonete(DaMoneta, NuovaMoneta); Cambia(DalireA,AmmontareDaCamb,AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta,NuovaMoneta, AmmontareDaCamb,AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s'] END.

25 PROCEDURE Cambia(DaLirA:ArrayConversione;VAR
BEGIN Istruzioni; DammiCambi(DaLireA); REPEAT DammiMonete(DaMoneta, NuovaMoneta); Cambia(DalireA,AmmontareDaCamb,AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta,NuovaMoneta, AmmontareDaCamb,AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s'] END. PROCEDURE Cambia(DaLirA:ArrayConversione;VAR AmmDaCamb, AmmCambiato:real); BEGIN write(' Introduci ammontare da cambiare: '); readln(AmmDaCamb); AmmCambiato:= AmmDaCamb*DaLirA[NuovaMoneta]/DaLirA[DaMoneta]; END;

26 PROCEDURE MostraQuadroRiepilogativo(DaMon, NuovaMon :
BEGIN Istruzioni; DammiCambi(DaLireA); REPEAT DammiMonete(DaMoneta, NuovaMoneta); Cambia(DalireA,AmmontareDaCamb,AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta,NuovaMoneta, AmmontareDaCamb,AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s'] END. PROCEDURE MostraQuadroRiepilogativo(DaMon, NuovaMon : TipoMoneta; AmmDaCamb, AmmCambiato: real;VAR Risp:char); BEGIN write('Converti '); write(AmmDaCamb:4:2,' '); MostraCambio(DaMon); write(' in '); write(AmmCambiato :4:2,' '); MostraCambio(NuovaMon); writeln; write('Mi posso riposare? '); readln(Risp) END;

27 { ******************* BODY *********************** }
BEGIN Istruzioni; DammiCambi(DaLireA); REPEAT DammiMonete(DaMoneta, NuovaMoneta); Cambia(DalireA, AmmontareDaCamb, AmmontareCambiato); MostraQuadroRiepilogativo(DaMoneta,NuovaMoneta, AmmontareDaCamb,AmmontareCambiato, Risposta) UNTIL Risposta IN ['S','s'] END.

28 ALGORITMI DI RICERCA LINEARE
Problema: Cercare tra i valori contenuti in un Array un preassegnato valore. Es.: Data una lista di N numeri verificare se esiste un preassegnato Valore. 10 19 98 30 29 12 18 1 2 3 4 5 6 7 Indice  Data la lista Cerca se in essa è contenuto il numero 12

29 Indice  valore iniziale dell’indice Trovato  false
Algoritmo 10.1 Controlla se abbiamo esaminato tutti gli elementi dell’array Indice  valore iniziale dell’indice Trovato  false WHILE NOT finito AND NOT Trovato DO IF UnArray[Indice]=ValoreCercato THEN Trovato  true ELSE Indice  nuovo valore dell’indice IF NOT Trovato THEN Indice  0 Condizioni di uscita: - la ricerca è finita se nessun elemento uguale a quello cercato esiste - la ricerca è finita se almeno un elemento uguale a quello cercato è stato trovato

30 Una maniera ovvia è quella di partire dall’ultimo elemento della
I criteri per stabilire il nuovo valore da attribuire all’indice possono essere i più diversi. E’ però importante che una volta stabilito che un elemento individuato da un certo indice non è quello cercato questo elemento non venga più esaminato. Una maniera ovvia è quella di partire dall’ultimo elemento della lista e risalire fino in cima nella ricerca dell’elemento. Algoritmo 10.2 Indice  NumeroTotaleElementi Trovato  false WHILE NOT (Indice=0) AND NOT Trovato DO IF UnArray[Indice]= ValoreCercato Trovato  true ELSE Indice  Indice-1 Se Indice=0 significa che non abbiamo trovato l’elemento cercato.

31 Indice:=CercaIndice(Nome, NumeroElementi,ValoreCercato);
Poiché ad ogni passo della ricerca eliminiamo un elemento il massimo numero di passi è pari al numero di elementi, di qui anche il nome di Algoritmo di Ricerca Lineare. Array di nomi Stringa Indice:=CercaIndice(Nome, NumeroElementi,ValoreCercato); IF Indice<>0 THEN BEGIN write(ValoreCercato,’ è stato trovato nella posizione ‘,Indice:2); END ELSE write(ValoreCercato,’ non è stato trovato ‘);

32 Uso di una sentinella per eliminare la variabile booleana
FUNCTION CercaIndice(VAR Nome: NomeArray; NumeroElementi:integer; ValoreCercato:NomeStringa):integer; VAR Indice:integer; Trovato: boolean; BEGIN WHILE NOT (Indice=0) AND NOT Trovato DO IF Nome[Indice]=ValoreCercato THEN Trovato:= true ELSE Indice:= Indice-1; CercaIndice:= Indice END. Uso di una sentinella per eliminare la variabile booleana sentinella FUNCTION CercaIndice(VAR Nome: NomeArray; NumeroElementi:integer; ValoreCercato:NomeStringa):integer; VAR Indice:integer; BEGIN Nome[0]: =ValoreCercato; Indice:=NumeroElementi; WHILE Nome[Indice]<>ValoreCercato DO Indice:= Indice-1; Nome[0]=‘’; CercaIndice:= Indice END;

33 ORDINAMENTO = SORTING 10 19 9 30 29 12 18 1 2 3 4 5 6 7 9 10 19 12 18 30 29

34 PROCEDURE OrdinaInteri(VAR Interi: ArrayInteri);
CONST UltimoElemento=7; TYPE ArrayInteri=ARRAY[1.. UltimoElemento] OF integer; VAR Interi:= ArrayInteri; BEGIN …………… END;

35 FOR Ordine  1 TO UltimoElemento-1 DO
I° Approccio FOR Ordine  1 TO UltimoElemento-1 DO scambia gli elementi nel sub-range Ordinati..UltimoElemento Ipotesi di lavoro: Per ogni algoritmo che progetteremo, una volta ordinata una parte della lista, ad esempio da 1 a Ordine, i rimanenti elementi presenti nella parte da Ordine+1 fino a UltimoElemento sono tutti maggiori in valore di qualunque elemento appartenente alla parte della lista già ordinata. Tutti ordinati UltimoElemento Tutti di valore maggiore agli ordinati 1 Ordine Ordine +1

36 BUBBLE SORT Pseudo-codice
FOR Indice  UltimoElemento-1 DOWNTO Ordinato DO IF Interi[Indice]> Interi[Indice+1] THEN Scambia(Interi[Indice], Interi[Indice+1] )

37 Ordinato=1 Ordinato=2 Ordinato=3 Ordinato=4 10 19 9 30 29 12 18 10 19 9 12 30 29 18 9 10 19 12 30 29 18 9 10 19 12 18 30 29 9 10 12 19 18 30 29 9 10 12 18 19 29 30 9 10 12 19 18 29 30 10 19 9 30 29 12 18 10 19 9 12 30 29 18 9 10 19 12 30 29 18 9 10 19 12 30 18 29 9 10 12 19 18 30 29 9 10 12 19 18 29 30 9 10 12 19 18 29 30 9 10 12 18 19 29 30 9 10 12 19 18 29 30 10 19 9 30 12 29 18 10 9 19 12 30 29 18 9 10 19 12 18 30 29 9 10 12 19 18 30 29 9 10 12 19 18 29 30 9 10 12 19 18 29 30

38 N° confronti: (n-1)+(n-2)+…+1=(n-1)*n/2
Ordinato=5 Ordinato=6 Ordinato=7 9 10 12 18 19 29 30 9 10 12 18 19 29 30 9 10 12 18 19 29 30 9 10 12 18 19 29 30 9 10 12 18 19 29 30 9 10 12 18 19 29 30 N° confronti: (n-1)+(n-2)+…+1=(n-1)*n/2

39 PROCEDURE BubbleSort(Var Interi:ArrayInteri);
Ordina, Indice :1..UltimoElemento; BEGIN FOR Ordinato:=1 TO UltimoElemento-1 DO FOR Indice:=UltimoElemento-1 DOWNTO Ordinato DO IF Interi[Indice]> Interi[Indice+1] THEN Scambia(Interi[Indice],Interi[Indice+1] ) END; PROCEDURE Scambia(Var Int1,Int2:integer); VAR Temp:integer; BEGIN Temp:= Int1; Int1:= Int2; Int2:= Temp; END;

40 Ordinamento per selezione
SELECTION SORT Ordinamento per selezione E’ un poco più efficiente del Bubble perché effettua solo una sostituzione ad ogni giro del loop. Pseudo-codice FOR Ordina  1 TO UltimoElemento-1 IndiceMinimo  valore dell’indice dell’elemento più piccolo nel sub-range Ordina..UltimoElemento-1 Scambia(Interi(Ordina),Interi(IndiceMinimo))

41 10 19 9 30 29 12 18 1 10 19 9 30 29 12 18 3 1 10 19 9 30 29 12 18 3 1 10 19 9 30 29 12 18 3 1 10 19 9 30 29 12 18 3 1 10 19 9 30 29 12 18 3 1 Ordina=1 9 19 10 30 29 12 18 3 2 9 19 10 30 29 12 18 3 2 9 19 10 30 29 12 18 3 2 9 19 10 30 29 12 18 3 2 9 19 10 30 29 12 18 3 2 Ordina=2 9 10 19 30 29 12 18 3 9 10 19 30 29 12 18 3 9 10 19 30 29 12 18 6 3 9 10 18 30 29 19 12 6 3 Ordina=3 SELECTION SORT

42 N° confronti: (n-1)+(n-2)+…+1=(n-1)*n/2
9 10 12 30 29 19 18 5 4 9 10 12 30 29 19 18 6 4 9 10 12 30 29 19 18 7 4 Ordina=4 9 10 12 18 30 29 19 6 5 9 10 12 18 29 30 19 7 5 Ordina=5 N° confronti: (n-1)+(n-2)+…+1=(n-1)*n/2 9 10 12 18 19 30 29 7 6 9 10 12 18 19 29 30 7 Ordina=6 SELECTION SORT

43 SELECTION SORT PROCEDURE SelectionSort(Var Interi:ArrayInteri); VAR
Ordina, Indice, IndiceMinimo :1..UltimoElemento; BEGIN FOR Ordina:=1 TO UltimoElemento-1 DO IndiceMinimo:=Ordina; FOR Indice:= Ordina+1 TO UltimoElemento DO IF Interi[Indice]< Interi[IndiceMinimo] THEN IndiceMinimo:=Indice; Scambia(Interi[IndiceMinimo],Interi[Ordina] ) END END;

44 Ordinamento per inserimento
INSERTION SORT Ordinamento per inserimento E’ l’algoritmo più intuitivo. Se ad esempio si ha un mazzo di carte non ordinato possiamo ordinarlo scorrendo le carte una alla volta e inserendo ogni carta immediatamente dopo la carta più piccola tra quelle che la precedono. Supponiamo che il primo elemento sia già ordinato. Pseudo-codice FOR PostoSuccessivo  2 TO UltimoElemento DO sposta tutti gli elementi maggiori di Interi[PostoSuccessivo ] di un posto in avanti e metti Interi[PostoSuccessivo ] nella sua giusta posizione

45 Interi[1] UltimoElemento Tutti ordinati Non ancora ordinati 63 11 61 65 Inserisci tra questi due elementi Interi[PostoSuccessivo] 33 Algoritmo Supponiamo di essere al passo j. Confrontiamo il valore dell’elemento di Interi[j] con i suoi predecessori. Se chi lo precede ha un valore più elevato lo spostiamo di un posto in avanti. Se incontriamo nella posizione i un valore più basso allora poniamo in Interi[i+1]  Interi[j].

46 Pseudo-codice Temp  Interi[PostoSuccessivo] Posizione  PostoSuccessivo-1 WHILE Interi[Posizione ] > Temp DO Interi[Posizione+1]  Interi[Posizione] Posizione  Posizione -1 Potrebbe succedere che uno degli elementi sia più piccolo di tutti e che quindi noi, risalendo la lista cerchiamo di confrontarlo con l’elemento posto in Interi[0] provocando così un crash. Per evitare questo definiamo il range dell’array Interi variabile tra 0..UltimoElemento e ogni volta che scegliamo un valore per eseguire i confronti lo memorizziamo temporaneamente in Interi[0], così che se esso fosse il più piccolo di tutti comunque verrebbe posto in Interi[0+1]

47 PostoSuccessivo 10 19 9 30 29 12 18 [0] [1] [2] [3] [4] [5] [6] [7] 2 3 10 19 9 30 29 12 18 [0] [1] [2] [3] [4] [5] [6] [7] 9 10 19 30 29 12 18 9 10 19 30 29 12 18 4 9 10 19 30 29 12 18 [0] [1] [2] [3] [4] [5] [6] [7] 5 9 10 19 30 29 12 18 [0] [1] [2] [3] [4] [5] [6] [7] 29 9 10 19 30 12 18

48 N° confronti: (n-1)+(n-2)+…+1=(n-1)*n/2
9 10 19 29 30 12 18 [0] [1] [2] [3] [4] [5] [6] [7] 6 12 9 10 19 29 30 18 12 9 10 19 29 30 18 12 9 10 19 29 30 18 7 [0] [1] [2] [3] [4] [5] [6] [7] 12 9 10 19 29 30 18 18 9 10 12 19 29 30 18 9 10 12 19 29 30 18 9 10 12 19 29 30 N° confronti: (n-1)+(n-2)+…+1=(n-1)*n/2

49 PROCEDURE InsertionSort(VAR Interi: ArrayInteri);
PostoSuccessivo, Posizione: 0..UltimoElemento; BEGIN FOR PostoSuccessivo:=2 TO UltimoElemento DO Interi[0]:=Interi[PostoSuccessivo]; Posizione:= PostoSuccessivo-1; WHILE Interi[Posizione]>Interi[0] DO Interi[Posizione+1]:= Interi[Posizione]; Posizione:=Posizione-1 END; Interi[Posizione+1]:=Interi[0] END

50 IL CORSO TERMINA IL 17 GENNAIO PRIMA PROVA SCRITTA IL 22 GENNAIO
PER SOSTENERE L’ESAME BISOGNA AVERE CONSEGUITO UNA VOTAZIONE TRA A-D SIA PER LA PROVA SCRITTA SIA PER IL PROGETTO CHE VA CONSEGNATO ALLEGANDO UNA RELAZIONE E IL FLOPPY DISK AL PIU’ TARDI 10 GIORNI PRIMA DELL’ESAME ORALE

51 REQUISITI MINIMALI PER IL PROGETTO
Pseudo Codice Rappresentazione grafica Relazione Programma Pascal

52 ALGORITMO DI RICERCA BINARIA
Data una lista di N elementi ordinati cercare se tra essi esiste un determinato elemento. Dividiamo gli elementi ordinati in due parti. Quello che cerchiamo può appartenere o alla prima o alla seconda parte, essendo tutti gli elementi ordinati. Dividiamo la parte scelta ancora in due e applichiamo ancora il ragionamento precedente. L’algoritmo termina o quando l’ultimo elemento rimasto dalle successive suddivisioni è uguale a quello cercato, oppure quando l’intervallo rimasto non è più suddivisibile il che implica che il nostro elemento non appartiene alla lista.

53 Supponiamo di vedere se 19 appartiene alla seguente lista
10 12 19 20 29 30 [1] [2] [3] [4] [5] [6] [7] 19 20 29 30 [4] [5] [6] [7] 2 19 20 [4] [5] 3 19 [4] 4

54 Condizioni di uscita A - il valore cercato è stato trovato (Flag booleano = TRUE) B - il valore cercato non è stato trovato (espressione che indichi questa condizione) Quando riducendo i sub-range Basso>Alto e il valore cercato non è stato trovato allora esci NOT Basso>Alto oppure Basso<=Alto

55 Pseudo-codice Uso di un flag booleano
Basso  1 Alto  ElementiTotali Trovato  false WHILE (Basso<=Alto) AND NOT Trovato DO BEGIN Metà  (Basso+Alto) DIV 2 IF Interi[Metà ] = ValoreCercato THEN Trovato = true ELSE IF Interi[Metà ] < ValoreCercato THEN Basso  Metà+1 Alto  Metà-1 END IF Trovato THEN Indice  Metà Indice  0 Pseudo-codice Uso di un flag booleano [ ] ValoreCercato=30 Indice=7 Metà Basso Alto 4 1 7 6 5 7 7 7 7 ValoreCercato=11 Indice=4 Metà Basso Alto 4 1 7

56 Senza flag booleano Condizioni di uscita Si cerca l’intervallo entro il quale il valore cercato potrebbe trovarsi. Questa ricerca termina quando modificando di volta in volta gli indici Basso e Alto non si verifica una inversione dei valori. A questo punto si esce dal ciclo e si verifica se l’elemento che si trova nella posizione Basso è quello cercato. Nel caso di risposta positiva l’indice sarà Basso altrimenti sarà 0.

57 Basso Alto Meta Interi[Meta] 1 7 4 10 5 7 6 40 5 5 5 30 6
Alto:=ElementiTotali WHILE Basso <= Alto DO BEGIN Meta:=(Basso+Alto) DIV 2; IF Interi[Meta]< ValoreCercato THEN Basso:=Meta+1; ELSE Alto:=Meta-1; IF Basso <= ElementiTotali THEN IF Interi[Basso]= ValoreCercato THEN Indice:=Basso Indice:=0; END; [ ] Basso Alto Meta Interi[Meta] 6

58 NOTAZIONE ASINTOTICA W (n log n) ( ) ( ) O(n log n) g(n) f(n) n f(n)
bound Upper " * = n g c f O O(n log n) f(n) g(n) n ( ) bound Lower " * W = n g c f W (n log n)

59 Definiamo complessità di un algoritmo il numero di passi massimo
previsto perché esso termini. La valutazione di complessità di un algoritmo va fatta sul caso peggiore che detto algoritmo si potrebbe trovare ad affrontare. Ad esempio nel caso dell’algoritmo di ricerca lineare il caso peggiore si presenta quando il valore cercato si trova all’ultimo posto della lista. Quindi la complessità di tale algoritmo è O(N) se N sono gli oggetti della lista. N f(N) g(N) 100

60 Ogni volta che si introduce un loop su N elementi avremo una
complessità pari a O(N). Ovviamente due loop annidati uno dentro l’altro avranno complessità O(N2) e così via. Gli algoritmi di sort proposti: Bubble, Selection e Insertion hanno tutti complessità pari a O(N2) avendo ognuno due loop annidate. L’algoritmo per LA TOMBOLA ha complessità pari a O(N)

61 L’algoritmo di Ricerca Binaria ha una complessità pari a O(log2N).
Infatti ad ogni passo noi dividiamo il numero N totale di elementi su cui cercare il valore richiesto per 2 e facciamo un solo confronto per passo. Se N è il numero totale di elementi quante volte dobbiamo dividere N per due affinchè diventi uguale o minore di 1? N N/2 N/4 …… N/ 2k N= 2k k= log2N

62 N=10.000.000 log2(N)=23,25 Ciclo = 10-6 sec T= 10-6 * 107=10 sec
32 N= log2(N)=23,25 Ciclo = 10-6 sec T= 10-6 * 107=10 sec Ciclo = 10-6 sec T= 10-6 * 23 sec LINEARE 1000*10=10.000sec=2,7 h BINARIA 1000*23* 10-6 = 23* 10-3 sec=23 ms

63 IN GENERE PER GLI ARRAY SI USA LA CHIAMATA PER VARIABILE
Le chiamate degli array per valore e per variabile sottostanno agli stessi criteri validi per le variabili classiche: la chiamata per valore non modifica il contenuto dell’array dopo il suo utilizzo nell’ambito della procedura mentre quella per variabile lo modifica. Nel caso della chiamata di un array per valore un FOR interno trasferisce elemento per elemento l’array nell’area dati prendendo quindi tempo di computazione e occupando, anche se temporaneamente spazio di memoria. Nel caso della chiamata di un array per variabile nell’area dati viene memorizzato solo l’indirizzo del primo elemento dell’array e per gli altri elementi se richiesti gli indirizzi vengono calcolati di volta in volta. Quindi minore tempo di calcolo, in media, e minore spazio occupato in area dati.

64 Supponiamo di avere un Programma che chiama la procedura di
Ricerca Binaria. Se tra programma e procedura passiamo l’array con i dati mediante una chiamata per valore allora noi avremo un numero di chiamate pari a O(N), più il numero di passi necessari per la ricerca, pari a O(log2N). La complessità totale sarà quindi data da O(N+log2N)O(N) Se invece tra programma e procedura passiamo l’array con i dati mediante una chiamata per variabile (passiamo solo l’indirizzo) allora noi avremo un numero di chiamate pari a O(1) più sempre il numero di passi necessari alla ricerca pari a O(log2N). La complessità totale sarà quindi data da O(1+log2N)= O(log2N)

65 Quando si hanno due algoritmi che risolvono lo stesso problema
ma hanno diverse complessità, ovviamente si deve scegliere quello con complessità più piccola. A parità di complessità vanno considerati diversi altri fattori sia legati all’uomo che alla macchina. Ad esempio un programma un poco più lento di un altro ma con una codifica semplice può essere preferito perché se suscettibile di modifiche o manutenzioni frequenti il costo per modificarlo è più basso.

66 SUGGERIMENTI Controllare che i dati digitati siano coerenti con quelli che il programma si aspetta. Usando gli array controllare sempre che gli indici attraverso cui si gestisce l’array non assumano valori esterni al sub-range di definizione.

67 Quando si progettano algoritmi di sorting fare test sui casi estremi (es. array già ordinato, array ordinato in ordine inverso, etc.) ricordando che le possibili disposizioni degli oggetti in un array sono n! dove n è il numero di elementi dell’array . Per la ricerca binaria fare i seguenti test: Cercare l’elemento in prima posizione Cercare l’elemento in ultima posizione Cercare un elemento tra la prima e l’ultima posizione Controllare il caso in cui si è in presenza di elementi duplicati.

68 ESERCIZIO Scrivere un algoritmo di ricerca binaria su un array ordinato che indichi se l’elemento cercato appartiene all’array e se è presente più volte. Es. INPUT ArrayOrdinato [ ] ValoreCercato: 6 OUTPUT Il valore cercato 6 appartiene all’array e ricorre 3 volte.


Scaricare ppt "CAPITOLO 10."

Presentazioni simili


Annunci Google