La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Programmazione Mod A - Cap 4 - prof. Burattini 1.

Presentazioni simili


Presentazione sul tema: "Programmazione Mod A - Cap 4 - prof. Burattini 1."— Transcript della presentazione:

1 Programmazione Mod A - Cap 4 - prof. Burattini 1

2 2 Le istruzioni di selezione nidificate Diremo che unistruzione di selezione è nidificata se esiste almeno unaltra istruzione di selezione contenuta in essa. Una tipica istruzione nidificata è composta da più comandi if …… poste luna dentro laltra. Per esempio: if (a>b) istruzione 1; else if (ab allora esegui istruzione 1 altrimenti (cioè a può essere minore o uguale a b ) se (ab) istruzione 1; if (a

3 Programmazione Mod A - Cap 4 - prof. Burattini 3 A titolo esemplificativo riprendiamo la risoluzione dellequazione di primo grado ax+b=0 Sappiamo che essa ammette la soluzione x =-b/a se a è diverso da 0, altrimenti dobbiamo controllare il valore di b; se anche b è nullo allora lequazione è soddisfatta da qualsiasi valore di x; si dice che lequazione è indeterminata; altrimenti lequazione non ammette nessuna soluzione, si dice che lequazione è impossibile. PseudocodiceCODICE C++ if (a!=0) { x=-b/a; cout<

4 Programmazione Mod A - Cap 4 - prof. Burattini 4 La nidificazione dellistruzione if ……..else ………. è spesso fonte di errori; consideriamo il problema seguente: Assegnati tre numeri riscriverli in modo ordinato. Ad esempio dati i tre numeri non ordinati numero1=14 numero2=28 numero3=18 al termine dellalgoritmo la variabile numero1 dovrà contenere ancora 14 in numero2 ci sarà 18 ed in numero3 ci sarà 28. Si consideri il seguente algoritmo: If (numero1>numero2 ) Scambia(numero1,numero2) else if (numero1>numero3) Scambia(numero1,numero3) else if (numero2>numero3) Scambia(numero2,numero3) Applicando lalgoritmo alla nostra terna di numeri osserviamo che essendo numero1

5 Programmazione Mod A - Cap 4 - prof. Burattini 5 LALGORITMO PRECEDENTE E ERRATO. Si consideri ad esempio la terna come input essa sarà trasformata in dal nostro algoritmo. Le istruzioni precedenti non risolvono il problema per la semplice ragione che esse implicano un solo scambio, mentre in genere ciò non è vero. Consideriamo, invece, le istruzioni seguenti : if (Numero1>Numero2) Scambia (Numero1,Numero2); if (Numero1>Numero3) Scambia (Numero1,Numero3); if (Numero2>Numero3) Scambia (Numero2,Numero3); Eseguiamo il testing dei cammini, determinando le precondizioni e le postcondizioni di ogni istruzione if (cond)..…. Se Numero1 Numero2 allora i due numeri vengono scambiati. Se Numero1 Numero3 possiamo scambiarli in modo che laffermazione sia soddisfatta. Al termine dei primi due if in Numero1 si troverà il numero più piccolo dei tre. Lo stesso accade nel caso del terzo confronto Numero2<=Numero3. Al termine del terzo if in Numero2 ci sarà un valore minore o uguale a quello contenuto in Numero3 per cui effettivamente lo stato finale al termine dei tre if sarà: Numero1<=Numero2<=Numero3

6 Programmazione Mod A - Cap 4 - prof. Burattini 6 Esaminiamo ora un esempio in cui il numero di istruzioni if ……. else …… nidificate sia maggiore. Un negozio vende solo articoli aventi tutti uno stesso prezzo. Inoltre se si acquistano più di 10 pezzi si avrà uno sconto del 10%, se più di 25 lo sconto sarà del 15% per salire al 25% per chi acquista più di 50 pezzi. Si vuole sapere, avendo acquistato n pezzi quanto si deve pagare. In questo caso è evidente che occorre esaminare varie alternative e quindi ricorrere ad istruzioni if then else nidificate. Ricorrendo al metodo dei raffinamenti successivi cominciamo a considerare la prima alternativa quella in cui non si ha diritto ad uno sconto: leggi(prezzo, pezzi) k pezzi*prezzo if(pezzi<=10) conto k else.. altri casi Sappiamo che listruzione che segue lelse sarà eseguita solo se sono stati acquistati più di dieci pezzi ed è evidente che occorre procedere considerando i vari casi in ordine crescente rispetto al valore di pezzi, quindi else..altri casi può essere sostituito con else if(pezzi<=25) conto 0.90*k (postcond. Pezzi maggiore di 10 e non superiore a 25) else … casi in cui pezzi è maggiore di 25.

7 Programmazione Mod A - Cap 4 - prof. Burattini 7 Avremo in definitiva il seguente algoritmo: leggi(prezzo, pezzi) k pezzi*prezzo if(pezzi<=10) conto k (post. Pezzi minore di 10 ) else if(pezzi<=25) conto 0.90*k (post: pezzi maggiore di 10 e non superiore a 25) else if(pezzi<=50) conto 0.85*k (post: pezzi maggiore di 25 e non superiore a 50) else pezzi 0.75*k (post: pezzi maggiore di 50)

8 Programmazione Mod A - Cap 4 - prof. Burattini 8 Ricapitolando si può dire che se bisogna effettuare n test distinti (quattro nel nostro esempio), ad ognuno dei quali corrisponde una azione alternativa (un differente valore di conto), occorre adoperare n-1 else innestati secondo il seguente schema: ALGORITMO if..else if If cond1 azione1 else if cond2 azione2 else ………… else if condn-1 azionen-1 else azione n

9 Programmazione Mod A - Cap 4 - prof. Burattini 9 Esiste un particolare operatore, detto operatore condizionale, che rappresenta unistruzione if … else …. estremamente compattata. Supponiamo di voler inserire nella variabile intera x il più grande dei valori interi tra a e b: if (a>b) x=a; else x=b; Invece adoperando loperatore condizionale ? scriveremo: (a > b) ? x=a : x=b;

10 Programmazione Mod A - Cap 4 - prof. Burattini 10 Loperatore ? ha la seguente forma: (condizione ) ? istruzione1 : istruzione2; prima del punto interrogativo cè la condizione che può essere vera o falsa, mentre dopo si ha la situazione seguente: se la condizione è vera, allora va eseguita istruzione1 ; se la condizione è falsa, allora va eseguita istruzione2. Un altro esempio è il seguente: assegnato un intero n determinare se è pari o dispari. (n % 2==0) ? cout<

11 Programmazione Mod A - Cap 4 - prof. Burattini 11 Espressioni booleane composte. Le espressioni booleane composte si ottengono dalle espressioni booleane semplici precedentemente introdotte (a

12 Programmazione Mod A - Cap 4 - prof. Burattini 12 Supponiamo che a e b siano due numeri interi; allora listruzione if ((a==0) && (b==0)) cout<< a e b sono entrambi nulli; scrive a e b sono entrambi nulli soltanto se è vero che sia il valore contenuto in a che quello contenuto in b sono nulli; listruzione if ((a==0) || (b==0)) cout<

13 Programmazione Mod A - Cap 4 - prof. Burattini 13 Ricordiamo le leggi di De Morgan che risultano estremamente utili: (A B) è equivalente a A B In C++ potremmo scrivere: ! ((A) &&(B) ) == !(A) ||! (B) ! ((A) || (B) ) == !(A) && !(B) Esercizio: Scrivere un programma che mostri la correttezza delle leggi di De Morgan Un esempio è dato dalle seguenti istruzioni che permettono di scrivere tutti i numeri interi tra 1 e 100 che non sono divisibili per 10 (un numero è divisibile per 10 quando è divisibile per 2 e per 5) : i=0 i=0; while (i<100) { i++; if ! ((i % 2==0) && (i % 5==0)) if ! (i % 2 ==0) || !(i % 5==0) cout<< i ; cout<< i; }

14 Programmazione Mod A - Cap 4 - prof. Burattini 14 Si noti che lespressione booleana (A1) && (A2) && …&&(An) è valutata nel seguente modo: appena si incontra una A che valuta a falso la computazione dellespressione viene interrotta, le A successive non sono valutate e si ritorna il valore falso per lintera espressione. Analogamente per lespressione A1 || A2 || … || An si ritorna il valore vero non appena si incontra una A che valuta a vero. In questo modo non solo si velocizza la computazione ma lespressività del linguaggio ne risulta potenziata. Ad esempio si può scrivere: if((a!=0 ) &&(b/a

15 Programmazione Mod A - Cap 4 - prof. Burattini 15 Lequazione di 2° grado Problema Assegnata la generica equazione di 2° grado Ax 2 + Bx + C = 0 dove A, B e C sono numeri reali trovare le soluzioni. Chiamiamo discriminante il valore della espressione

16 Programmazione Mod A - Cap 4 - prof. Burattini 16 Input : A, B, C Output: Caso equazione non quadratica Se A=B=C=0 questa è una tautologia Se A=B=0 e C<>0 questa non è una equazione Se A=0 e B e C <>0 questa è una equazione lineare che ammette una radice pari a -C/B. Caso equazione quadratica degenere Se A<>0 e B e C=0 questa equazione ammette una soluzione pari a 0 Se A e B <>0 e C=0 questa equazione ammette due soluzioni: una pari a 0 e la seconda pari -B/A Caso equazione quadratica con due radici Se A, B e C <> da 0 e >0 ammette due radici reali distinte Se A, B e C <> da 0 e <0 ammette due radici immaginarie Se A, B e C <> da 0 e =0 ammette due radici reali uguali e coincidenti pari a -B/2A

17 Programmazione Mod A - Cap 4 - prof. Burattini 17 Prima osservazione: se A=0 allora lequazione non è quadratica. Pseudo-codice Introduci A, B, C Se A=0 allora MostraEqNonQuadr(B,C) altrimenti gestisci lequazione quadratica Pseudo-codice Introduci A, B, C Se A=0 allora MostraEqNonQuadr(B,C) altrimenti Se C=0 allora MostraRadiciDegenerate(A,B) altrimenti MostraDueRadici(A,B,C)

18 Programmazione Mod A - Cap 4 - prof. Burattini 18 Pseudo-CodiceMostraEqNonQuadr scrivi: equazione non quadratica Se B=0 allora NonEquazione altrimenti scrivi esiste una radice pari a -C/B Pseudo-CodiceNonEquazione Se C=0 allora scrivi tautologia altrimenti scrivi non è una equazione Pseudo-CodiceMostraEqNonQuadr scrivi: equazione non quadratica Se B=0 allora Se C=0 allora scrivi tautologia altrimenti scrivi non è una equazione altrimenti scrivi esiste una radice pari a -C/B

19 Programmazione Mod A - Cap 4 - prof. Burattini 19 Pseudo-Codice MostraRadiciDegeneri precondizioni C=0 A<>0 B qualunque Se B=0 allora scrivi due radici degeneri altrimenti scrivi una radice degenere pari a 0 scrivi unaltra radice pari a, -B/A Pseudo-Codice MostraDueRadici precondizioni A,C <>0 B qualunque Discrim sqr(B) - 4*A*C Se Discrim >=0 allora RadiciReali altrimenti RadiciComplesse

20 Programmazione Mod A - Cap 4 - prof. Burattini 20 Analizziamo i vari casi. Il primo, caratterizzato da a=0, porta allequazione di primo grado, equazione non quadratica, mentre gli altri due casi si distinguono dal valore di c, nullo per lequazione quadratica degenere, diverso da zero nel caso dellequazione con due radici. Se il coefficiente a è nullo risolvi lequazione non quadratica altrimenti se anche c è nullo lequazione è degenere altrimenti è unequazione con due radici

21 Programmazione Mod A - Cap 4 - prof. Burattini 21 #include // Calcolo Equazione II grado using namespace std; void NonQuadratica (double, double, double&); void QuadraticaDegenere (double, double, double&, double&); void Quadratica (double, double, double, double&, double&); int main () { double a,b,c,x1,x2; char ch='s'; while (ch!='n') { cout <<"Programma che calcola le radici delle equazioni di secondo grado"<a; cout >b; cout >c; if (a==0) NonQuadratica(b,c,x1); else if (c==0) QuadraticaDegenere(a,b,x1,x2); else Quadratica(a,b,c,x1,x2); cout<<"Continuare (s/n)? "; cin>>ch; }

22 Programmazione Mod A - Cap 4 - prof. Burattini 22 void NonQuadratica (double b,double c,double &x1) { if (b==0) { if (c==0) cout <<"Questa è una equazione indeterminata."<

23 Programmazione Mod A - Cap 4 - prof. Burattini 23 void QuadraticaDegenere (double a,double b,double& x1, double& x2) { if (b==0) { cout<<"L`equazione ammette due radici reali e coincidenti uguali a zero"<

24 Programmazione Mod A - Cap 4 - prof. Burattini 24 void Quadratica (double a,double b,double c,double &x1,double &x2) { double delta; char segno='+'; delta= b*b - 4*a*c; if (delta>0) { cout<<"L`Equazione ammette due radici reali e distinte."<

25 Programmazione Mod A - Cap 4 - prof. Burattini 25 else //delta <= 0 if (delta<0) { cout<<"L`Equazione ha radici complesse coniugate"<

26 Programmazione Mod A - Cap 4 - prof. Burattini 26 /* Sia assegnato un vettore di interi (max 255) VettIn. Porre all'inizio di V i valori di V pari e di seguito quelli dispari senza cambiare l'ordine Esempio INPUT: VettIn = OUTPUT: VettIn = */ PSEUDO CODICE LeggiDati(Vett, n, k); OrdSubVet(Vett, n,k, j); StampaDati(Vett, n); system("PAUSE"); }

27 Programmazione Mod A - Cap 4 - prof. Burattini 27 // PROTOTIPI void StampaDati(int [],int); void LeggiDati(int [],int&, int&); void scambia(int&,int&); void OrdSubVet(int [],int,int,int&); // MAIN int main() { int Vett[M], n, j=0, k; LeggiDati(Vett, n, k); OrdSubVet(Vett, n,k, j); StampaDati(Vett, n); system("PAUSE"); return EXIT_SUCCESS; } // DEFINIZIONI void OrdSubVet(int V[], int N, int K, int &j) // ordina i numeri pari e dispari { int k; for(int i=1;ij) { scambia(V[k],V[k-1]); k--; } j++; } paridispari

28 Programmazione Mod A - Cap 4 - prof. Burattini 28 ESERCIZI. 1) I compiti scritti sono valutati con il seguente criterio: A=ottimo tra B=buono tra C=sufficiente tra D= incerto tra E=insufficiente Scrivere un programma che, assegnato un certo voto compreso tra 1 e 30, scriva la lettera corrispondente e viceversa, assegnata la lettera, stampi la scritta posta alla sua destra. 2) Rivedere il programma del MCD in modo che non accetti numeri negativi o nulli. 3) Calcolare in una frase qual è la vocale che occorre più volte. 4)Scrivere un programma che simuli una calcolatrice per numeri razionali: si assegnano due stringhe nella forma a/b che rappresentano i due numeri razionali ( per esempio 3/5 e 5/6 ). Il programma deve determinare i due numeri e poi, alla richiesta di una certa operazione ( +, -, *, : ) deve restituire il risultato sotto forma di frazione. Se per esempio riceve in input : 3/5 5/6 * deve restituire 1/2

29 Programmazione Mod A - Cap 4 - prof. Burattini 29 Istruzioni switch, break Listruzione switch offre un altro modo per implementare strutture di selezione con diverse alternative. Prima di mostrare la struttura dellistruzione switch ricordiamo il tipo ordinale. Tipo ordinale: quando è possibile definire il precedente (tranne il primo) ed il successivo (tranne lultimo) di ogni valore. I tipi int, longint, char ad esempio sono ordinali.

30 Programmazione Mod A - Cap 4 - prof. Burattini 30 Osservazioni: -espressione: può essere una variabile od una espressione di tipo ordinale; -la parola-chiave case deve essere seguita da una costante il cui valore Risultato1, Risultato2,….è coerente con lespressione; -istruzioni1, istruzioni2,… sono sequenze di istruzioni che non devono essere delimitate da parentesi graffe; -la parola-chiave break è essenziale: -una volta che il compilatore C++ incontra la parola case ed il Risultato voluto, esegue solo le istruzioni corrispondenti ignorando completamente i case seguenti ed il default; -il caso default può essere omesso; esso rappresenta il caso in cui il Risultato di (espressione) non corrisponde a nessuno dei Risultati previsti ( è diverso da Risultato1,Risultato2, …. RisultatoN). Listruzione switch ha la seguente struttura: switch (espressione) { case Risultato1: istruzioni1; break; case Risultato2; istruzioni2; break; ………………….. case RisultatoN: istruzioniN; break; default: istruzioni di default; }

31 Programmazione Mod A - Cap 4 - prof. Burattini 31 ESEMPIO: Supponendo che in una scuola siano assegnati dei giudizi corrispondenti ai voti da 3 a 10 secondo lo schema successivo, scrivere listruzione switch relativa: Switch (voto) { case 3: case 4: case 5: cout <

32 Programmazione Mod A - Cap 4 - prof. Burattini 32 Luso dellistruzione switch corrisponde alla seguente istruzione if …. else… nidificata if (espressione==Risultato1) { istruzioni1; } else if (espressione==Risultato2) else …………………….. else if (espressione==RisultatoN) { istruzioniN; } else { istruzioni di default; }

33 Programmazione Mod A - Cap 4 - prof. Burattini 33 ESERCIZI. a) Scrivere un programma che propone le tabelline per un bambino delle elementari. I due fattori da moltiplicare sono generati in modo random ed il computer deve controllare che lutente risponda esattamente. Quando risponde esattamente, il programma deve generare a caso una delle seguenti risposte: 1) Bravo!! 2) Ottima risposta. 3) Continua così!! 4) Stai nettamente migliorando. Nel caso di una risposta errata deve rispondere, sempre a caso, con una delle seguenti: 1)1) Errato. Riprova. 2) Non è la risposta esatta. 3) Fai più attenzione. Riprova 4) Non arrenderti. Prova ancora. b) Scrivere una procedura che date la base e laltezza di un triangolo ne stampi larea, una seconda che date la base e laltezza di un rettangolo ne stampi larea ed infine una terza che stampi larea di unellisse dati i due assi. c) Scrivere un main che legge due numeri reali ed un carattere: se il carattere è T chiama la prima procedura, se il carattere è R chiama la seconda, se è E chiama la terza, se è N esce dal ciclo inviando un messaggio di saluto, altrimenti stampa: carattere errato.

34 Programmazione Mod A - Cap 4 - prof. Burattini 34 Il ciclo do…while..... Nella prima parte abbiamo considerato i cicli while …… e for(…..). In entrambi i casi, se la condizione di ingresso è falsa allorché viene valutata la prima volta, il corpo del ciclo non viene mai eseguito. Allorché si è sicuri che il corpo del ciclo dovrà essere eseguito almeno una volta si può utilizzare listruzione do …. while : do { corpo del ciclo } while (espressione booleana) Con questa istruzione il sistema esegue una prima volta il corpo del ciclo, successivamente valuta lespressione booleana e solo se questa è falsa esce dal ciclo, altrimenti esegue un altro passo

35 Programmazione Mod A - Cap 4 - prof. Burattini 35 Esempio : dato un array A contenente n elementi si vuole verificare se la somma dei suoi elementi è maggiore di un certo valore k. sum=0 i=0 do { sum=sum+A[i]; i++ } while ((ik) cout<

36 Programmazione Mod A - Cap 4 - prof. Burattini 36 Invariante di loop Come dobbiamo ragionare per verificare che un algoritmo che adoperi un loop sia stato scritto in modo corretto? Lespressione booleana tra parentesi che segue la parola riservata while è detta condizione di ingresso, se tale condizione risulta verificata il corpo del loop deve essere ripetuto, allorché è falsa il controllo passa alla istruzione immediatamente successiva allistruzione while. Esempio 1- Supponiamo che dato un intero n si voglia calcolare il prodotto di tutti i numeri da uno fino ad n (anche detto Fattoriale di n e scritto come n!). Avremo: while(cond) i i+1 prodotto prodotto*i La condizione di uscita dal loop è i=n e la condizione di ingresso, che è la negata della condizione di uscita, sarà: i n. Avremo: while(i n) i i+1 prodotto prodotto*i

37 Programmazione Mod A - Cap 4 - prof. Burattini 37 Le due variabili i e prodotto devono essere inizializzate prima dellenunciato while. Ovviamente prodotto deve essere inizializzato ad 1 ed anche i deve avere lo stesso valore: i 1 prodotto 1 while(i n) i i+1 prodotto prodotto*i Possiamo dire che al termine di ogni passo i è dato da 1 più il numero di passi effettuati nel loop e prodotto è il prodotto dei primi i numeri. Alluscita definitiva dal loop i deve valere n e prodotto conterrà esattamente il prodotto dei primi n numeri. Linvariante di loop è data da: prodotto= prodotto dei primi i numeri e 1<=i<=n;

38 Programmazione Mod A - Cap 4 - prof. Burattini 38 Esempio ( Problema dei polli e dei conigli di Leonardo Pisano detto Fibonacci – 1200 ) In una fattoria ci sono polli e conigli. Sapendo che sono state contate 260 zampe e 100 teste, determinare il numero di polli e di conigli. Il nostro scopo è quello di determinare il numero dei polli mentre il numero dei conigli sarà automaticamente determinato eseguendo la sottrazione teste – polli; la variabile polli può assumere un valore compreso tra 1 e teste. Dal problema si evince ancora che : Numero di zampe = 2 * polli + 4 * conigli Le precondizioni e le postcondizioni relative allalgoritmo sono: PRE: Input : teste, zampe con teste e zampe interi positivi POST : 1) 0<= polli<=teste 2) conigli = teste - polli 3) 2 x polli + 4 x conigli = zampe Risolvere il problema significa risolvere il sistema formato dalle equazioni 2) e 3) e vedere se ammette soluzioni intere. Noi invece per poter usare un loop preferiamo prendere in considerazione ogni numero compreso tra 0 e teste (100 nel nostro problema) e verificare se soddisfa le due condizioni Per determinare il corpo del loop osserviamo che, per la 1), la variabile polli deve essere incrementata di uno ad ogni passo del ciclo, mentre la variabile conigli deve essere posta uguale a teste - conigli.

39 Programmazione Mod A - Cap 4 - prof. Burattini 39 Dunque avremo: while (condizione) polli polli +1 conigli teste-polli Si dovrà uscire dal loop non appena la condizione 3) risulti verificata, dunque la sua negata rappresenta la condizione di ingresso al loop: ( 2* polli +4*conigli zampe) Potremo quindi scrivere: while (2* polli +4*conigli zampe) polli polli +1 conigli teste - polli Poiché le grandezze variabili nel corpo del loop compaiono entrambe nella condizione di ingresso esse devono essere inizializzate prima del loop. Per la 1) polli dovrà quindi assumere il minimo valore possibile cioè 0 e di conseguenza conigli dovrà inizialmente essere uguale a teste, dando così: polli=0 conigli=teste while (2* polli +4*conigli zampe) polli polli +1 conigli teste - polli

40 Programmazione Mod A - Cap 4 - prof. Burattini 40 Linvariante di loop è data da: (0 <= polli<=teste) and (conigli = teste – polli) and (( 2*polli + 4*conigli zampe) or (2 polli + 4*conigli = zampe)) Prima di mostrare lalgoritmo generale osserviamo che, per come era stato enunciato il problema, si era presupposto che esistesse esattamente una soluzione rappresentata da numeri interi; questo è vero nellesempio proposto (teste= 100 e zampe= 260), ma non è vero in generale. In altre parole, non tutte le coppie teste, zampe ammettono soluzioni intere. Tale situazione si presenta quando il ciclo viene completamente eseguito senza che sia stata verificata la condizione 2 polli + 4 conigli = zampe. In tal caso alluscita dal ciclo si ha polli>teste; è questa la condizione da testare per verificare se ci sono soluzioni.

41 Programmazione Mod A - Cap 4 - prof. Burattini 41 Leggi( teste, zampe) polli=0 conigli teste while (2*polli – 4*conigli zampe) and ( polli <= teste) { polli polli +1 conigli teste – polli } If ( polli <= teste) Stampa( polli, conigli) Else Stampa( messaggio) ALGORITMO GENERALE PER RISOLVERE IL PROBLEMA DEI POLLI E DEI CONIGLI

42 Programmazione Mod A - Cap 4 - prof. Burattini 42 #include using namespace std; main () { int polli,conigli,teste,zampe; cout<<"Inserire numero teste="; cin>>teste; cout<<"Inserire numero zampe="; cin>>zampe; polli=0; conigli=teste; while ((2*polli+4*conigli)!=zampe) && polli<=teste) { polli=polli+1; conigli=teste-polli; } if (polli<=teste) cout<<"Polli="<

44 Programmazione Mod A - Cap 4 - prof. Burattini 44 Un caso di studio: il calcolo della radice quadrata. Il modo più semplice per calcolare la radice quadrata di un numero a è quello di utilizzare un algoritmo molto antico, usato dai babilonesi, e riproposto da Erone, che consiste nellutilizzare la formula ricorrente Xs = _________________ 2 dove Xp è il valore precedente e Xs è quello successivo. Per poter applicare questa formula è necessario assegnare un valore iniziale a Xp; poiché Xp appare anche al denominatore poniamo come valore iniziale Xp=1. X p + a X p Volendo calcolare la radice di 2, seguiamo i primi passi dellalgoritmo: Xp=1 Xs=(1+2)/2=1,5 Poniamo ora Xp=1,5 Xs=(1,5+2/1,5)/2=1,416 Poniamo ora Xp=1,416 e così via

45 Programmazione Mod A - Cap 4 - prof. Burattini 45 Lalgoritmo di Erone di Alessandria (vissuto tra il I° e II° sec. d.C.) utilizza solo le quattro operazioni dellaritmetica. Lalgoritmo si basa su considerazioni geometriche. Per calcolare la radice di un numero l costruiamo un quadrato di area l, il suo lato è proprio la radice di l. Utilizziamo il metodo delle approssimazioni successive e partiamo da un rettangolo i cui lati misurano h e l/h, scegliamo h minore di l. Larea del rettangolo è cioè è uguale allarea del quadrato che cerchiamo. I lati sono invece uno minore e uno maggiore del lato del quadrato.

46 Programmazione Mod A - Cap 4 - prof. Burattini 46 Calcolando la media aritmetica delle misure dei due lati del rettangolo, otteniamo dove h 1 è maggiore di h. Costruiamo un nuovo rettangolo i cui lati misurano h 1 e

47 Programmazione Mod A - Cap 4 - prof. Burattini 47 Anche in questo caso larea del rettangolo è cioè uguale a quella del quadrato, h 1 è un valore approssimato per eccesso del lato del quadrato, è un valore approssimato per difetto. Però la media aritmetica delle due approssimazioni ha fornito un valore h 1 più vicino a l di quanto lo fosse h. Calcolando di nuovo la media aritmetica delle misure dei due lati del rettangolo, otteniamo dove h 2 è maggiore di h 1 e sempre minore di l.

48 Programmazione Mod A - Cap 4 - prof. Burattini 48 Si costruisce il rettangolo i cui lati misurano h 2 e. Si otterranno un valore approssimato per eccesso del lato del quadrato e un valore approssimato per difetto. Il valore di h 2 è più vicino a l di quanto lo fosse h 1. Proseguendo per successive approssimazioni possiamo costruire due successioni di numeri che approssimano, una per eccesso e una per difetto, la radice quadrata di l.

49 Programmazione Mod A - Cap 4 - prof. Burattini 49 passo1 Quadrato da costruire l =400 h 1040 passo passo3 20,519,5 …………. 20 h

50 Programmazione Mod A - Cap 4 - prof. Burattini 50 Possiamo controllare la differenza tra Xs e Xp: se questa è minore di un numero piccolo prefissato ( che indichiamo con Y ), allora lalgoritmo ha termine. Indicando con esegui la variabile booleana che rappresenta la sentinella possiamo scrivere un primo raffinamento dellalgoritmo. Leggi(a) Xp=1 Esegui true while esegui Calcola xs if abs(Xs-Xp)

51 Programmazione Mod A - Cap 4 - prof. Burattini 51 Programma in C++ Pseudo-Codice #include using namespace std; // Calcola radice quadrata main () { const float eps= ; float a,xs,xp ; bool esegui; // precondizioni: a>=0 and eps>0 cout << " Calcolo della radice di a: a="; cin >> a; xp=1.0; esegui=true; while (esegui) { xs=(xp+a/xp)/2; if (fabs(xs-xp)0 and xp>0 and (xs-xp)

52 Programmazione Mod A - Cap 4 - prof. Burattini 52 Unaltra maniera di gestire il ciclo è la seguente: #include using namespace std; // Calcola radice quadrata main () { const float eps= ; float a,x ; // precondizioni: a>=0 and eps>0 cout << " Calcolo della radice di a: a="; cin >> a; x=1.0; while (fabs(x-a/x)/2>=eps) x=(x+a/x)/2; //Postcondizioni: x>0 |x-a/x|

53 Programmazione Mod A - Cap 4 - prof. Burattini 53 Esercizi. Supponiamo di dover prendere decisioni sullacquisto di unazione. Per fare questo lagente di cambio decide sulla base dellandamento giorno per giorno dellazione stessa. Assegnato allora un intervallo di tempo in giorni, scriviamo il prezzo dellazione giorno per giorno. Introduciamo un contatore che contiene il numero di giorni nei quali lazione è aumentata rispetto al giorno precedente e un contatore nel quale registriamo i giorni nei quali è calata. Non registriamo i giorni in cui lazione è rimasta invariata. Scrivere un programma che, assegnato un certo numero N di giorni ed il prezzo dellazione giorno per giorno, restituisca il numero totale dei giorni in cui lazione è aumentata ed il numero totale dei giorni in cui lazione è diminuita.

54 Programmazione Mod A - Cap 4 - prof. Burattini 54 Categorie di problemi che possono essere risolti con luso di cicli Esistono alcune tipologie di problemi già standardizzati per i quali è utile dividere i problemi in categorie in maniera tale che una volta individuato lo schema opportuno si dovrà soltanto adattare lo schema al caso particolare per poter scrivere lalgoritmo in pseudo-codice. Per ogni categoria di problemi forniamo lalgoritmo in pseudo-codice, qualche indicazione sugli invarianti ed un esempio. Ci serviamo del termine evento, per indicare una istruzione che, una volta eseguita, cambia una parte dello stato del programma, ad esempio una istruzione di assegnazione. Come esercizio si consiglia di tradurre ogni esempio nel linguaggio C++.

55 Programmazione Mod A - Cap 4 - prof. Burattini 55 Conteggio di una successione di eventi Invarianti: - ValoreEvento = il valore di ValoreEvento è quello associato allultimo valore introdotto della sequenza, - ContaEventi = Numero di Eventi conteggiati nella sequenza. ContaEventi = 0 Ottieni ValoreEvento while (ValoreEvento rappresenta un evento da contare ) ContaEventi ContaEventi + 1 ottieni ValoreEvento Utilizzando la struttura do …. while..... si ottiene lalgoritmo seguente da adoperare solo se si è certi che la successione di eventi non è vuota Contaeventi= 0 do ottieni ValoreEvento If (ValoreEvento rappresenta un evento da contare ) ContaEventi ContaEventi + 1 while (ValoreEvento rappresenta un evento da contare) Esempio: trovare quante volte occorre ricalcolare la variabile x nellesempio precedente del calcolo della radice quadrata. Basta inserire nellalgoritmo i due enunciati relativi a contaeventi. Qui levento in questione è lenunciato: x=(x+a/x)/2, ValoreEvento è dato dai successivi valori di x, a partire dal valore iniziale uguale ad 1.

56 Programmazione Mod A - Cap 4 - prof. Burattini 56 Conteggio di eventi selezionati. ContaEventi 0 while (ci sono eventi da processare ) ottieni ValoreEvento If (ValoreEvento soddisfa la proprietà) ContaEventi ContaEventi + 1 Invarianti: - ValoreEvento = il valore di ValoreEvento è quello associato allultimo valore della sequenza introdotto, - ContaEventi = Numero di Eventi significativi conteggiati nella sequenza. ESEMPIO Dato un array disordinato di N interi contarne i numeri positivi. Contatore 0; Passo 0; while Passo0 THEN Contatore Contatore+1 passo passo+1 Stampa(Contatore) Qui levento è rappresentato da passo, ValoreEvento da A[passo]

57 Programmazione Mod A - Cap 4 - prof. Burattini 57 Accumulazione di eventi Per accumulazione intendiamo un processo per cui il precedente valore di una variabile viene combinato con il valore di un nuovo evento; tale combinazione dei valori ( esempio tipico somma o prodotto ) avviene in una variabile detta variabile daccumulazione. ACCUMULAZIONE SOMMA Somma 0 while (ci sono eventi da processare ) introduci ValoreEvento Somma=Somma+ValoreEvento Invarianti: - ValoreEvento = il valore di ValoreEvento è quello associato allultimo valore introdotto della sequenza, -Somma = Somma di tutti gli Eventi - il cui valore è stato assegnato. ESEMPIO Sommare tutti gli elementi di un array di N interi. Somma=0 i=0 while ( i

58 Programmazione Mod A - Cap 4 - prof. Burattini 58 Accumulazione di eventi selezionati. A questa categoria appartengono quei problemi in cui partecipano allaccumulazione solo eventi che soddisfano una prefissata proprietà ACCUMULAZIONE SOMMA Somma 0 while (ci sono eventi da processare ) introduci ValoreEvento if (ValoreEvento soddisfa la proprietà) Somma Somma+ValoreEvento ESEMPIO 4.4 Assegnati 5 numeri da tastiera sommare solo i numeri positivi Somma 0; Passo 0; while Passo<5 Passo Passo+1 Leggi(Numero) if Numero>0 THEN Somma Somma+Numero i i+1 stampa( Somma) Invarianti: -ValoreEvento = il valore di ValoreEvento è quello associato allultimo valore introdotto della sequenza, -Somma = Somma degli Eventi significativi della sequenza.

59 Programmazione Mod A - Cap 4 - prof. Burattini 59 Tecnica dellevento Sentinella. Accade spesso di processare una sequenza di eventi finché non si verifica un dato evento. Questo rappresenta un evento terminale: il loop termina dopo che esso è stato inserito. Diremo che un evento è un Evento Sentinella se è un evento che produce la terminazione di un loop. Ottieni ValoreEvento while ( ci sono eventi da processare andValoreEvento non è un evento sentinella) elabora ValoreEvento Ottieni ValoreEvento Invarianti: -ValoreEvento = il valore di ValoreEvento è quello associato allultimo valore introdotto della sequenza, -Tutti gli eventi eccetto lultimo, sono stati processati Lalgoritmo dellevento sentinella si adopera ogni volta che si devono elaborare tutti gli elementi di un array contenente N elementi. Qui valore evento è il valore dellindice del generico elemento dellarray, che quindi va inizializzato a zero, il valore di sentinella è N (ma si potrebbe inizializzare lindice a N-1 con sentinella –1).

60 Programmazione Mod A - Cap 4 - prof. Burattini 60 Algoritmo di skipping Viene adoperato allorché si vuole cercare il primo degli eventi di una successione che soddisfa una determinata proprietà: Ottieni ValoreEvento while ValoreEvento non soddisfa la proprietà Ottieni Valore evento Esempio: leggi(c) while c!= leggi(c) Salta tutti i blank e si arresta sul primo carattere diverso da blank (spazio vuoto). Naturalmente lalgoritmo funziona solo se si è sicuri che prima o poi apparirà un evento con la proprietà cercata.

61 Programmazione Mod A - Cap 4 - prof. Burattini 61 Algoritmo esiste Algoritmo per stabilire se in una successione di eventi esiste almeno un valore avente una data proprietà: trovato false Ottieni ValoreEvento while ci sono eventi da processare and (not trovato) if ValoreEvento soddisfa la proprietà trovato true else ottieni ValoreEvento Al termine del ciclo la variabile booleana trovato sarà True se un tale elemento esiste False altrimenti.

62 Programmazione Mod A - Cap 4 - prof. Burattini 62 Algoritmo Tutti Questo algoritmo serve per stabilire se tutti i valori della successione di eventi godono di una prefissata proprietà: ok=true ottieni ValoreEvento while ci sono ancora eventi and ok if lelemento non soddisfa la proprietà ok false else ottieni ValoreEvento Semplicemente si cerca se esiste un elemento che non abbia la proprietà, invertendo i valori assegnati alla variabile booleana

63 Programmazione Mod A - Cap 4 - prof. Burattini 63 ESERCIZI. 1) Utilizzando i costrutti while, do..while e for, scrivere un programma che stampi la tabella seguente: x x+3 x+7 x ) Si scriva un programma che riceva da input una serie di interi non nulli e stampi su video il valore minimo, il valore massimo e la somma dei valori negativi. 3) Dato un array di N elementi scrivere una funzione che restituisce il più piccolo indice, se esiste, cui corrisponde un numero primo, zero altrimenti. 4) Dato un array di N elementi, scrivere una funzione che restituisca true se tutti gli elementi sono pari.

64 Programmazione Mod A - Cap 4 - prof. Burattini 64 Cicli nidificati Quando un ciclo racchiude al suo interno un altro ciclo, diciamo di avere due cicli nidificati (nested loops). Quando il programma viene lanciato, viene eseguito prima il ciclo più esterno e dopo quello più interno. Ovviamente, termina prima il loop interno e dopo quello esterno. Se un problema richiede, per la sua soluzione, almeno due cicli nidificati, conviene progettare prima il loop esterno e dopo quello interno.

65 Programmazione Mod A - Cap 4 - prof. Burattini 65 Esempio Assegnato un numero intero N, compreso tra 1 e 20, rappresentare sullo schermo un quadrato di asterischi. Per risolvere il problema dobbiamo usare due cicli nidificati; quello più esterno fissa la riga, quello più interno la colonna. Il loop esterno lascia la stampa della linea di asterischi al ciclo interno ed al termine di esso va a capo. Il ciclo interno stampa N asterischi. Per esempio, per N=4 si ha: **** Primo raffinamento. for ( i=0; i < N; i++ ) stampa una linea con N asterischi vai a capo Lesempio 1 può essere facilmente completato per scrivere un programmino nel linguaggio C++ ( attenzione alle parentesi graffe! ). Secondo raffinamento. for ( i=0; i < N; i++ ) for ( k=0; k < N; k++ ) cout<<*; cout<

66 Programmazione Mod A - Cap 4 - prof. Burattini 66 Quali modifiche vanno apportate al programma precedente per rappresentare il triangolo seguente? * ** *** **** Proponiamo un primo raffinamento: for ( i=0; i < N; i++ ) stampa una linea con i+1 asterischi vai a capo * ** *** **** * *** ***** ******* Esercizio. Scrivere un programma completo che, assegnato un numero intero N, disegni le seguenti figure (negli esempi N=4 ):

67 Programmazione Mod A - Cap 4 - prof. Burattini 67 Esempio Stampare i valori comuni a due vettori V1 e V2 di lunghezza, rispettivamente N1 ed N2. Il ciclo esterno legge ogni singolo elemento di V1, si tratta dunque di un for. Nel ciclo interno, il generico lelemento V1[i] viene confrontato con ogni elemento di V2; se lelemento di V1[i] viene trovato in V2, allora si stampa lelemento si esce dal ciclo interno relativo a V2. Si tratta dunque di un caso particolare dellalgoritmo esiste, dove la proprietà da verificare è se il generico elemento V2[j] del vettore V2 è uguale a V1[i] In definitiva, possiamo scrivere: for ( i=0; i < N1; i++ ) k 0 ; trovato false; while (k

68 Programmazione Mod A - Cap 4 - prof. Burattini 68 Esercizi. 1) Scrivere il programma completo relativo allesempio 2. In seguito variare il programma in modo tale da inserire in un nuovo vettore V di lunghezza N da determinare, dato dallintersezione di V1 e V2. Il programma dovrà stampare alla fine il vettore V. 2) Apportare al programma opportune modifiche nel caso in cui i due vettori V1 e V2 siano: uno ordinato in ordine crescente e laltro no; ambedue ordinati in ordine crescente. Si consiglia di strutturare ogni programma in procedure e funzioni ( servendosi anche delle procedure contenute nella libreria sugli array ).


Scaricare ppt "Programmazione Mod A - Cap 4 - prof. Burattini 1."

Presentazioni simili


Annunci Google