ALGORITMO DI EUCLIDE PER IL CALCOLO DEL MASSIMO

ALGORITMO DI EUCLIDE PER IL CALCOLO DEL MASSIMO COMUN
DIVISORE
Dati:
INPUT  a,b, (coppia di numeri interi) >= 0
OUTPUT  mcd (numero intero) >=0
Proprietà:
1. Se a=b  mcd(a,b)=a=b
2. Se a>b  mcd(a,b)=mcd(a-b, b)
3. Se a<B  mcd(a,b)=mcd(a, b-a)
Considerazioni:
La prima proprietà afferma che il massimo comun divisore di (a,b)
è proprio a oppure b. Le altre due proprietà affermano che il mcd
di (a,b) si può ricondurre al calcolo del massimo comun divisore di
(a-b, b) oppure (a, b-a).
Idea dell’algoritmo:
 Poiché valgono le proprietà precedenti, nel caso generale si
possono calcolare tante differenze in modo da riportarsi al caso
a=b, per il quale il problema è risolto.
 Il calcolo delle differenze deve essere ripetuto se risulta
verificata la condizione a≠b.
 Si può utilizzare una iterazione a condizione iniziale (while …)
Pseudocodifica:
mentre (a≠b)
while (a != b)
se (a>b)
if (a>b)
a  a-b
a  a-b
altrimenti b  b-a
else b  b-a
fine
mcd  a
mcd  a
CALCOLARE L’ENNESIMO NUMERO DI FIBONACCI
Introduzione:
La successione di Fibonacci è definita per n>=0
n=0  f(0)=0
n=1  f(1)=1
n>1  f(n)=f(n-1)+f(n-2)
La successione di Fibonacci è una successione di interi:
0, 1, 1, 2, 3, 5, 8, 13, 21, …
I primi due elementi sono 0 ed 1. L’elemento n-mo per n>=2 si
ottiene sommando i 2 elementi precedenti.
Dati:
INPUT  n (numero intero) >=0
OUTPUT  fib (numero intero) >=0
VARIABILI  fib1 (per memorizzare l’ultimo numero calcolato),
fib2 (per memorizzare il penultimo numero calcolato), fib (per
memorizzare il nuovo numero).
Notazione lineare:
Se (n == 0) Allora fib ← 0
Altrimenti
Se if (n==1) Allora fib ← 1
Altrimenti
{ Calcola fib1, fib2
fib ← fib1 + fib2
inizializza contatore i con il valore 2
Mentre ( i < = n )
{
calcola valore corrente di fib come
somma dei 2 valori
precedenti
aggiorna penultimo valore calcolato
fib2
aggiorna ultimo valore calcolato fib1
incrementa contatore i
} Fine
} Fine
Fine
Fine
Pseudocodifica:
/* Precondizione dell’algoritmo : n>=0 */
/* Postcondizione dell’algoritmo : fib >=0 */
if (n == 0) fib=0
else if (n==1) fib=1
else
{ fib2 =0
fib1 = 1
fib = 1
i=2
while ( i < = n )
{ /* Asserzione invariante */
/* INV: (fib1 = fib) and (fib1= f(i-1) ) and fib2 = f( i-2)
*/
fib = fib1 + fib2
fib2 = fib1
fib1 = fib
i = i +1 } }
RIMOZIONE DEGLI ELEMENTI RIPETUTI DI UN ARRAY ORDINATO
Introduzione:
Consideriamo un insieme a di n elementi dello stesso tipo t. Il
problema richiede di rimuovere i valori duplicati di a compattando
gli elementi non duplicati.
Esempio:
INPUT 
a={10,20,20,40,50,50}
n=4
OUTPUT  a={10,20,40,50}
n0=4
Dati:
INPUT 
n (numero intero) >=0
a (vettore di n elementi)
OUTPUT  n0 (numero intero con n0>0 and n0<=n)
a (vettore di n0 elementi)
Premessa e conseguenza:
PREMESSA  a è un vettore di n elementi ordinato in senso non
decrescente cioè a[i]<=a[i+1] per i che varia da 0 a (n-2) (N.B.: in a
vi possono essere valori ripetuti)
CONSEGUENZA  a è un vettore composto da n0 valori non
duplicati a[0]…a[n0-1] con n0<=n
/* Precondizione dell’algoritmo */
/* PREC: n>0 and (a è un vettore di n elementi
ordinato
in senso non decrescente) */
/* Postcondizione dell’algoritmo */
/* POST: n0>0 and a è un vettore di n0 elementi
aventi
valori non duplicati */
Algoritmo:
IDEA  10,20,20,40,50,50
 Confrontare tutti gli elementi del vettore a coppie a[i] con a[i+1]
– i varia da 0…n-2
 Se la coppia in esame ha elementi diversi, spostare uno dei 2
elementi all’indietro, se vi sono posizioni libere.
CONSIDERAZIONI  10,20,20,40,50,50
Il primo valore da spostare dovrebbe essere 40. Per fare lo
spostamento è necessario conoscere fino a quale indice j gli
elementi sono già stati compattati. Nell’esempio j=1 e 40 deve
essere copiato nella posizione 2.
L’algoritmo si può scrivere in due passi:
1. Ricerca della prima coppia di elementi duplicati – cioè trova
l’indice j tale che tutti gli elementi del vettore di indici 0…j siano
diversi tra loro.
2. Analizza gli elementi restanti – a partire da j – spostarli nelle
posizioni occupate dai valori da eliminare.
Pseudocodifica 1:
/* Inizializza l’indice j mediante la ricerca della prima coppia di
elementi duplicati */
i=0
while (i < n-1 & (la coppia a[i] e a[i+1] ha valori distinti) )
incrementa indice i
j=i
/* Asserzione: j>=0 and (gli elementi a[0]… a[j] hanno valori distinti)
cioè a[0]..[j] è compattato*/
/* Sposta i valori degli elementi restanti nelle posizioni occupate
dai valori da eliminare */
while ( i < n-1 )
{
if la coppia a[i] e a[i+1] ha valori distinti
{ Incrementa j
Sposta a[i+1] in a[j]
}
i = i +1 } }
n0 = j+1
Pseudocodifica 2:
/* Inizializza l’indice j mediante la ricerca della prima coppia di
elementi duplicati */
i=0
while ( i < n-1 and (a[i] != a[i+1]) )
i=i+1
j=i
/* Asserzione: j>=0 and (gli elementi a[0]… a[j] hanno valori distinti)
cioè a[0]..[j] è compattato*/
/* Sposta i valori degli elementi restanti nelle posizioni
occupate dai valori da eliminare */
while ( i < n-1 )
{
if ( a[i] != a[i+1]) {
j = j+1 // incrementa il numero j di elementi diversi
a[j] = a [i+1]// sposta a[i+1] in a[j]
}
i = i +1 } }
n0 = j+1
Codifica:
/* Precondizione dell’algoritmo */
/* PREC: n>0 and (a è un vettore di n elementi ordinato in senso
non decrescente) */
/* Postcondizione dell’algoritmo */
/* POST: n0>0 and a è un vettore di n0 elementi aventi valori non
duplicati */
/* Ricerca della prima coppia di elementi duplicati */
i=0;
while ( i < n-1 && a[i] != a[i+1] )
/* mentre (( vi sono coppie da esaminare ) and (la coppia di
elementi i e i+1 ha valori distinti ) )
i=i+1; // incrementa indice i
j=i ;
/* Ass: j>=0 and (gli elementi a[0]… a[j] hanno valori distinti) */
/* Sposta i valori degli elementi restanti nelle posizioni occupate
dai valori da eliminare */
while ( i < n-1 ) / * mentre vi sono ancora coppie da
esaminare */
{
if (a[i] != a[i+1] ) // la coppia di indici i e i+1 ha valori distinti
{ j=j+1; // incrementa il numero j di elementi diversi
a[j] = a [i+1]; // sposta a[i+1] in a[j]
}
i = i +1 }
n0= j+1;
INVERSIONE DEGLI ELEMENTI DI UN ARRAY
Introduzione:
Sia a un vettore di n elementi. Si vuole invertire l’ordine degli
elementi del vettore a (SENZA USARE UN VETTORE AUSILIARIO)
Es: VETTORE DI INGRESSO  1 2 3 4 5 6
Es: VETTORE DI USCITA  6 5 4 3 2 1
Pseudocodifica:
Calcoliamo l’indice dell’elemento centrale: m=parte intera (n/2)
 n pari: l’ultimo elemento da scambiare ha indice m-1
 n dispari: l’elemento di indice m è centrale e non va scambiato anche in questo caso l’ultimo elemento da scambiare ha indice
m-1
/*Pseudocodifica*/
Calcola m come parte intera (n/2)
Itera per i che varia da 0 a m-1
Scambia a[i] e a[n-1-i]
/* PRE: (a è un vettore di n elementi) and (n>0) */
/* POST: gli elementi di a sono in ordine inverso */
m = parte intera (n/2)
for (i=0; i<m; i++)
Scambia a[i] e a[n-1-i]
Trace:
Sia n= 8
a= 10, 20, 30, 40, 50, 60, 70,80
m= 8/2 = 4
i=0
a= 80, 20, 30, 40, 50, 60, 70, 10
i=1
a= 80, 70, 30, 40, 50, 60, 20,10
i=2
a= 80, 70, 60, 40, 50, 30, 20,10
i=3
a= 80, 70, 60, 50, 40, 30, 20,10
ALGORITMI DI RICERCA
Consideriamo un insieme a di elementi dello stesso tipo t ed un
valore x ti tipo t.
Il problema della ricerca richiede di definire se il valore x
appartiene oppure no all’insieme.
ESEMPIO:
a = {10,1,0,4,5}
x = 100  La risposta è SI – x è stato trovato
x = 100  La risposta è NO – x non è stato trovato
Ipotesi: in a non vi sono valori ripetuti
Analizziamo due diversi algoritmi di ricerca:
 ALGORITMO DI RICERCA LINEARE O ESAUSTIVA: non richiede
alcuna ipotesi di ordinamento dei dati a
 ALGORITMO DI RICERCA BINARIA: si applica solo quando i dati a
sono ordinati.
RICERCA BINARIA o ESAUSTIVA (usare ALGORITMO do…while)
Introduzione:
L’idea dell’algoritmo si può sintetizzare come: scandire ogni
elemento dell’insieme a e confrontarlo con il valore x da ricercare,
iniziando dal primo elemento. Terminare la scansione di a appena
il valore x viene trovato oppure non vi sono più elementi da
analizzare.
ALGORITMO (1° VERSIONE):
mentre (x non viene trovato e vi sono ancora elementi da
confrontare)
confronta x con ogni elemento dell’insieme a
Dati:
INPUT 
n (numero intero) >0
a (vettore di n elementi di tipo t)
x (valore di tipo t)
OUTPUT  trovato: {0, 1}
ALGORITMO (ciclo while):
trovato ← 0
i←0
Mentre (il valore x non è stato trovato ) and (vi sono altri elementi
da esaminare)
i ← i+1
Fine
Se (a[i] uguale x) trovato ← 1
Fine
/* L’ultimo controllo è necessario poiché la condizione di uscita dal
ciclo è (x è stato trovato) or (non vi sono altri elementi da
esaminare) */
ALGORITMO (ciclo while):
trovato ← 0
i←0
while ( a[i] !=x && i<n-1)
i ← i+1
if (a[i]==x)
trovato ← 1
Condizione di uscita dal ciclo: a[i] ==x || i>=n-1
ALGORITMO (ciclo do…while):
trovato ← 0 /* falso*/
i←0
do
if A[i]==x
trovato ← 1 /* vero */
i ← i+1
while (trovato ==0 && i < n)
RICERCA DELL’INDICE DI UN VALORE X
Introduzione: il problema della ricerca può richiedere di sapere se
un valore x appartenga oppure no ad un vettore a e in caso
affermativo quale posizione occupa.
ESEMPIO
a = {10,1,0,4,5}
x = 400  La risposta è SI – x è stato trovato in posizione 3
x = 100  La risposta è NO – x non è stato trovato
Dati:
INPUT 
n (numero intero) >0
a (vettore di n elementi di tipo t)
x (valore di tipo t)
OUTPUT  ind (di tipo int)
ind>=0 se il valore viene trovato
ind=-1 se x non viene trovato
Codifica:
trovato = 0;
i = 0; ind -1;
while ( a[i] !=x && i<n-1)
i=i+1;
if (a[i]==x)
ind =i;
RICERCA BINARIA
Introduzione:
A è un vettore di n elementi ordinati in senso crescente cioè
A[i]<A[i+1] per i che varia 0 a (n-2).
N.B.: in A non vi sono valori duplicati
IDEA  Confrontare il valore x con l’elemento centrale A[m] del
vettore A e proseguire la ricerca a destra o a sinistra dell’elemento
m in base all’esito del confronto.
Pseudocodifica:
trovato ← 0
Inizializza gli estremi dell’intervallo di ricerca –inf e sup
While (inf <=sup) and (not trovato)
Calcola la posizione centrale
m=Parte intera[(inf+sup)/2]
If x > A[m]
inf ← m+1
Else If x < A[m]
sup ← m-1
Else trovato ← 1
Legge e visualizza i valori di un vettore utilizza l'istruzione for
#include <stdio.h>
#define DIM 10 // dimensione del vettore
int main()
{
int a[DIM];
int i, n;
/* leggi n - numero di elementi n<=DIM */
printf("Numero di elementi del vettore, n<= %d ", DIM);
scanf("%d",&n);
if (n > DIM)
{ printf("errore nei dati\n");
}
else
{ /* leggi vettore */
printf("inserire %d valori separati da spazi ",n);
for (i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("\n");
/* SI PUO' INSERIRE IL CODICE PER ELABORARE a !!!!!!!!!
*/
ESERCIZI prof. ALTAMURA ORONZO
Questo programma legge dimV elementi di tipo intero; le
inserisce in un vettore e stampa il contenuto del vettore
#include <stdio.h>
#define dimV 10 //dimensione (numero massimo di elementi) del
vettore V
int main(){
int intero;
int nV, //Numero effettivo del vettore
i; //Variabile di controllo del ciclo
int v[dimV]={0}; //Oppure potremmo nascondere l'istruzione
iniziale #define dimV10 e scrivere, al posto di int v[dimV]={0}, int
v[10]={0};
{
int const FINE; //Variabile relativa al blocco {...}
printf("\nLegge e scrive interi usando un ciclo while\n");
printf("\nLa terminazione dipende dal valore di fine definito
durante l'esecuzione");
printf("\nNessun intero deve avere il valore di fine\n");
//Chiede di digitare il valore di fine
printf("\nDigita il valore di fine\n");
scanf("%d", &FINE);
printf("\nDigita gli interi separati da almeno uno spazio. ");
printf("Per terminare digita %d e premi INVIO\n", FINE);
nV=0;
scanf("%d", &intero);
//Ciclo di lettura
while(intero!=FINE){
v[nV]=intero;
nV++;
scanf("%d", &intero);
}
/* visualizza vettore */
for (i=0;i<n;i++)
{ // printf("%d\n", a[i]);
printf("%d ", a[i]); }
}
printf("\n");
system("pause");
return 0;
//Ciclo di scrittura
printf("\nElementi del vettore V: \n");
for (i=0; i<nV; i++) printf("%d ", v[i]);
printf("\n");
}
}
system("pause");
return(0);
}
Legge dim elementi di tipo carattere, li inserisce in un vettore e li
stampa
#include <stdio.h>
#define dimV 10
int main(){
char car;
int nV, //Numero effettivo di elementi del vettore
i; //Variabile di controllo del ciclo
char v[dimV] = {' '}; //Vettore di massimo dimV caratteri
inizializzato a ' '
//Lettura di una sequenza di caratteri
printf("\nQuesto programma legge e scrive un vettore di
caratteri");
printf("\nDigita una sequenza di massimo %d caratteri, non
contente spazi", dimV);
scanf("%c", &car);
//Ciclo di lettura
i=0;
while ((car!=' ')&&(car!='\n')&&(i<dimV)){
v[i]=car;
i++;
scanf("%c", &car);
}
nV=i; //Definizione del numero effettivo di elementi del vettore
V
printf("\nNumero di caratteri letti = %d", nV);
printf("\nLa sequenza dei caratteri letti e':");
for (i=0; i<nV; i++) printf("%c", v[i]); //Ciclo di stampa degli
elementi del vettore V
printf("%s", v);
system("pause");
return 0;
}
ESERICIZIO RICAPITOLAZIONE
Quesiti 31/10/2010 - Preparazione 1° Esonero
1) Contare il numero di volte in cui si ripete il valore MAX o il valore
MIN in un vettore di n elementi.
2) Visualizza elementi vettore
3) Valutare l'ipotesi in cui i valori del vettore siano interi ad un
intervallo[a,b], estremi inclusi, contare il numero di volte in cui
si presentano nel vettore a i valori dell'intervallo ( cioè calcolare
l'occorrenza di ogni valore dell'intervallo).
4) Contare il numero di elementi di un insieme che passiede una
proprietà.
5) Leggere un numero non prefissato di interi di un vettore a di DIM
elementi.
6) Uscire dal programma.
#include <stdio.h>
#define DIM 10
#define FineVettore -1
int main () {
int n,i,a,b,scelta,vett[DIM],cont=0;
do{
printf("\n\t\t\t*****ESERCIZI QUESITI*****");
printf("\n\n 1.Inserisci il numero massimo di elementi del vettore
e gli elementi stessi");
printf("\n\n 2.Visualizza elementi vettore");
printf("\n\n 3.Contare il numero di volte in cui si presentano nel
vettore i valori dell' intervallo impostato");
printf("\n\n 4.Contare il numero di elementi pari nel vettore");
printf("\n\n 5.Leggere un numero non prefissato di interi di un
vettore a di DIM elementi.");
printf("\n\n 6.Esci");
printf("\n\n\n\n Fai la tua scelta: ");
scanf("%d",&scelta);
switch(scelta){
/*1) Contare il numero di volte in cui si ripete il valore MAX o il
valore MIN in un vettore di n elementi*/
case 1:
Inserimento:
printf("\n\n1.Inserisci il numero massimo degli elementi del
vettore: ");
scanf("%d",&n);
if(n>DIM) {printf("\n\n\tATTENZIONE!!! LA DIMENSIONE
MASSIMA DEL VETTORE E' %d\n",DIM);
goto Inserimento;}
else {for(i=0;i<n;i++){printf("\n\nInserisci l'elemento %d del
vettore: ",i);
scanf("%d",&vett[i]);
}}
break;
/*2) Visualizza gli elementi del vettore*/
case 2:
printf("\n\n2.Visualizza elementi del vettore: ");
for(i=0;i<n;i++){printf("\n\nL'elemento %d del vettore e':
%d",i,vett[i]);}
break;
/*3) Valutare l'ipotesi in cui i valori del vettore siano interi ad un
intervallo[a,b], estremi inclusi, contare il numero di volte in cui si
presentano nel vettore a i valori dell'intervallo ( cioè calcolare
l'occorrenza di ogni valore dell'intervallo). */
case 3:
printf("\n\n2.Inserisci il valore minimo del intervallo: ");
scanf("%d",&a);
printf("\n\n Inserisci il valore massimo del intervallo: ");
scanf("%d",&b);
/* Se l'elemento i del vettore è compreso nell'intervallo a e b
allora si incrementa il contatore e stampiamo il numero e il numero
di elementi*/
for(i=0;i<n;i++){if(vett[i]>=a
&&
vett[i]<=b){printf("\n\nL'elemento
%d
e'compreso
nell'intervallo:(%d,%d)",vett[i],a,b);
cont++;}}
printf("\n\nIl numero di elementi del
vettore compresi nell'intervallo sono: %d",cont);
break;
/*4) Contare il numero di elementi pari.*/
case 4:
for(i=0;i<n;i++){if(vett[i]%2==0) printf("\n\nL'elemento %d =
%d e'pari",i,vett[i]);}
break;
/*5) Leggere un numero non prefissato di interi di un vettore vett
di DIM elementi*/
case 5:
i=0;
/* Legge l'elemento 0 del vettore*/
printf("\n\nInserisci l'elemento %d del vettore(-1 per
terminare): ",i);
scanf("%d",&vett[i]);
/* Mentre il vettore è diverso da -1 e minore della dimensione
massima,aumenta l'indice del vettore e legge l'elemento i del
vettore*/
while ((vett[i]!=FineVettore) && (i<DIM)){i++;
printf("\n\nInserisci l'elemento %d del vettore: ",i);
scanf("%d",&vett[i]);}
printf("\n\nNumero di elementi del vettore:%d\n",i);
/* Esci premendo 6 come scelta*/
case 6:
break;
default: printf("\n\nATTENZIONE SCELTA ERRATA");}
while(scelta!=6);
system("PAUSE");
return 0;
}