2000 prentice hall, inc. all rights reserved. capitolo 6 (deitel) i vettori sommario 6.1 -...

31
2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4 - Inizializzazione di vettori 6.5 - Esempio di uso dei vettori 6.6 - Vettori di caratteri 6.7 - Passare i vettori alle funzioni 6.8 - Ordinare i vettori 6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori 6.10 - Ricerca nei vettori: ricerca lineare e ricerca binaria 6.11 - Vettori multidimensionali

Upload: vitalia-caruso

Post on 02-May-2015

219 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

Capitolo 6 (Deitel)I vettori

Sommario

6.1 - Introduzione6.2 - Vettori6.3 - Dichiarazione di vettori6.4 - Inizializzazione di vettori6.5 - Esempio di uso dei vettori6.6 - Vettori di caratteri 6.7 - Passare i vettori alle funzioni 6.8 - Ordinare i vettori6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori6.10 - Ricerca nei vettori: ricerca lineare e ricerca binaria6.11 - Vettori multidimensionali

Page 2: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.1 - Introduzione

• Supponiamo di dover rappresentare N dati dello stesso tipo– La temperatura di ogni giorno di questo mese, o l’altezza degli studenti di

questa classe, o il valore di un titolo in borsa ad ogni ora di oggi, ecc..– Ognuno dei casi precedenti comprende un gran numero di dati omogenei– Con le conoscenze attuali, li rappresenteremmo con N variabili dello

stesso tipo, ma è davvero la scelta migliore?– Fortunatamente il C offre una soluzione più adatta a questa situazione

• Vettori (o array)– Costituiscono il primo tipo di dato strutturato che vedremo nel corso– Sono strutture dati statiche contenenti una serie di dati omogenei,

ovvero che hanno una caratteristica che li accomuna: il tipo– Esempi: una serie di numeri, una serie di caratteri, ecc..– Con il termine “statiche” si intende che hanno dimensione (numero di

elementi) prefissata e mai variabile durante l’esecuzione del programma– In C esistono anche strutture dati dinamiche, cioè la cui dimensione può

variare nel corso del programma• Verranno affrontate nei capitoli successivi

Page 3: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.2 - Vettori (1/2)

• Vettore– E’ una collezione di elementi dello stesso tipo

• Tale tipo individua il tipo del vettore

– E’ un’unica variabile, per cui tutti suoi elementi condividono un nome comune

• Tale nome individua il nome del vettore

– I valori dei vari elementi del vettore vengono memorizzati in locazioni di memoria contigue

• E’ una sequenza indicizzata di elementi– La cui dimensione è fissata e nota a priori– Per accedere ad un elemento, si deve specificare

il nome del vettore e il numero la sua posizione

• Sintassi: nome_vettore[indice]– Nell’esempio, contiene N elementi di nome c:

• c[0], c[1]...c[n-1]– Il primo elemento ha indice/posizione 0– L’i-esimo elemento ha indice/posizione i-1– L’ultimo elemento ha indice/posizione n-1

c[6]

-45

6

0

72

1543

-89

0

62

-3

1

6453

78

Nome del vettore (si noti che tutti gli elementi di questo vettore hanno lo stesso nome, c)

c[0]

c[1]

c[2]

c[3]

c[11]

c[10]

c[9]

c[8]

c[7]

c[5]

c[4]

Numero della posizione di ogni elemento all’interno del vettore c (indice)

Page 4: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.2 - Vettori (2/2)

• Ogni elemento di un vettore va trattato come una qualsiasi variabile dello stesso tipo– Sia per le operazioni di assegnamento di valori all’elemento, sia per le

operazioni che usano l’elemento per effettuare calcoli o stampa a video c[0] = 3;

printf( "%d", c[0] );

printf( "%d", c[0] + c[1] + c[2] );

x = c[2] / 2;

– Nell’accesso ad un elemento, l’indice può essere dato da una variabile precedentemente assegnata o perfino da un’espressione

• In tal si prende l’elemento in posizione pari al valore corrente della variabile o al risultato dell’espressione

• Se x=3, allora c[5-2] == c[3] == c[x]• Se a=5 e b=6, allora c[a+b]++ incrementa il 12° elemento del vettore c

Page 5: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.3 - Dichiarazione di vettori

• Un vettore viene dichiarato specificando:– Il nome dell’array, condiviso da tutti i suoi elementi– Il tipo del vettore, condiviso da tutti i suoi elementi– Il numero degli elementi contenuti (dimensione dell’array) Tipo_vettore Nome_vettore[Numero_elementi];– Esempi:

int c[ 10 ]; float MyArray[ 3284 ];

• Si noti che il C obbliga a specificare esplicitamente la dimensione (statica) del vettore in fase di dichiarazione– Non farlo comporta la generazione di un errore in compilazione– La dimensione è data da un numero o da una costante (#define..)

• Per dichiarare insieme più vettori dello stesso tipo– Si usa la stessa sintassi valida per ogni altra variabile semplice

int b[ 100 ], x[ 27 ];

Page 6: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.4 - Inizializzazione di vettori

• In fase di dichiarazione, un vettore può essere inizializzato– I suoi valori iniziali vanno specificati tra { } e separati da virgole

int n[5] = {1, 2, 3, 4, 5 }; – Se non ci sono abbastanza inizializzatori rispetto alla dimensione indicata

esplicitamente, gli elementi più a destra sono inizializzati a 0– Se invece ce ne sono troppi, si genera un errore di sintassi

• Solo quando si unisce dichiarazione e inizializzazione– Si può omettere la dimensione del vettore, in quanto automaticamente

determinata in base al numero di inizializzatori– Nel caso di int n[] = { 1, 2, 3, 4, 5 }; ho 5 inizializzatori,

perciò la dimensione del vettore viene fissata a 5 elementi

• Il C non ha meccanismi di controllo sui limiti dei vettori– Dato un vettore di dimensione N, quando si accede ad una posizione

superiore a (N-1) si ha un errore logico, non rilevato dal compilatore– Farlo può portare ad errori di indirizzamento (memory fault) o “sporcare”

altre variabili in memoria, rendendo così l’errore difficile da localizzare– E’ compito del programmatore fare in modo di non eccedere tali limiti

Page 7: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.5 - Esempio di uso dei vettori

1 /* Fig. 6.8: fig06_08.c - Visualizzazione di istogrammi */

2 #include <stdio.h>

3 #define SIZE 7

4

5 int main(){6 int n[ SIZE ] = { 19, 3, 15, 7, 11, 9, 13 };

7 int i, j;

8

9 printf( "%s%13s%17s\n", "Elemento", "Valore", “Istogramma" );10 for ( i = 0; i <= SIZE - 1; i++ ) {

11 printf( "%8d%13d ", i, n[ i ]) ;

12 for ( j = 1; j <= n[ i ]; j++ ) printf( "%c", '*' );13 printf( "\n" );

14 }15 return 0;

16 }

Elemento Valore Istogramma 0 19 ******************* 1 3 *** 2 15 *************** 3 7 ******* 4 11 *********** 5 9 ********* 6 13 *************

1. Inizializza il vettore

2. Ciclo per la

stampa di righe/colonne

Visualizzazione del programma

Page 8: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.6 - Vettori di caratteri (1/4)

• Vettori di caratteri (stringhe)– La stringa “first" può essere implementata come vettore di caratteri

• In tal caso ogni stringa di N lettere si traduce in un vettore di (N+1) caratteri

• N+1 perchè il C obbliga a terminare ogni stringa con il carattere nullo ‘\0’, che occuperà quindi l’ultima cella del vettore

– Ogni vettore di caratteri può essere inizializzato con una stringa posta tra doppi apici o dalla sequenza di caratteri tra { }, a patto che l’ultimo sia \0

char string1[] = “first";

char string1[] = { 'f', 'i', 'r', 's', 't', '\0' };• Il vettore string1 ha quindi effettivamente 6 elementi

• Nel primo caso, il carattere nullo è aggiunto a fine vettore automaticamente

• Lo stesso avviene se il vettore è inizializzato da una scanf con formato %s

– L’unico modo per inizializzarlo con la sequenza di caratteri omettendo il carattere nullo in coda è dare la dimensione del vettore esplicitamente

char string1[6] = { 'f', 'i', 'r', 's', 't' };• Anche in questo caso il carattere nullo è aggiunto in coda automaticamente

• Per evitare errori, si dà una dimensione maggiore del numero di caratteri

Page 9: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.6 - Vettori di caratteri (2/4)

• Si può usare un vettore di N caratteri per memorizzare anche stringhe più corte di N-1 caratteri – Così facendo le celle dopo quella contenente il carattere nullo sono

concettualmente vuote e di fatto contengono valori casuali (senza senso)– Mettere il carattere nullo permette di individuare la parte utile della

stringa

• Acquisizione di una stringa in input scanf( "%s", string2 ) ;– Il nome del vettore rappresenta l' indirizzo in memoria del vettore, per cui

la & non è necessaria nell scanf – Vengono acquisiti tutti i caratteri finchè si incontra il primo spazio bianco

• Tutto quello che scrivo dopo lo spazio viene inesorabilmente perso• Per acquisire frasi, servono altri metodi (es. più scanf in sequenza)

– Non essendoci controllo sui limiti, si deve fare attenzione anche qui• Non scrivere oltre la fine dichiarata del vettore (causa errori logici)

– Se invece la stringa è acquisita con un ciclo carattere per carattere• Attenzione che quando si preme invio, anch’esso è acquisito come carattere \n

Page 10: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.6 - Vettori di caratteri (3/4)

• Stampa della stringa– La si può stampare con un’unica printf con formato %s

• printf(“%s”,string1) che stampa tutti i caratteri fino a quello nullo

– Oppure la si stampa carattere per carattere, con un ciclo a sentinella avente flag pari ovviamente al carattere nullo

• Ad esempio printf (“%c”,string1[3]) stamperà il carattere 's'

• Gli errori logici più comuni (non rilevati dal compilatore):– Inizializzare la stringa omettendo sia la dimensione del vettore che il

carattere nullo di chiusura• Se la stampo con %s, ottengo una stringa diversa da quella desiderata • Se la stampo con il ciclo controllato da sentinella vado in loop infinito

– Inizializzare la stringa omettendo il carattere nullo di chiusura e mettendo una dimensione pari al numero di inizializzatori (escluso il carattere nullo)

• Se la stampo con %s, ottengo una stringa diversa da quella voluta • Se la stampo con il ciclo a sentinella vado in loop infinito

– Stampare i caratteri con indice che è oltre la dimensione del vettore• Stampa caratteri casuali senza senso, anche se era stato messo il carattere nullo

Page 11: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.6 - Vettori di caratteri (4/4)

1 /* Fig. 6.10: fig06_10.c2 Trattare un vettore di caratteri come una stringa */

3 #include <stdio.h>

4

5 int main(){

6 char stringa1[ 20 ], stringa2[] = "stringa letterale";7 int i;

8

9 printf(" Inserire una stringa: ");

10 scanf( "%s", stringa1 );11 printf( “La prima stringa è: %s\nLa seconda stringa è: %s\n

12 “La prima con gli spazi è:\n", stringa1, stringa2 );

13 for ( i = 0; stringa1[ i ] != '\0'; i++ )14 printf( "%c ", stringa1[ i ] );

15 printf( "\n" );

16 return 0;

17 }

Inserire una stringa: Ciao a tuttiLa prima stringa è: CiaoLa seconda stringa è: stringa letteraleLa prima con gli spazi è:C i a o

1. Inizializza i vettori di caratteri

2. Acquisisce la stringa3. Stampa i vettori come stringhe, direttamente

4. Ciclo per la stampa carattere per carattere inserendo degli spazi tra ogni carattere

Visualizzazionedel programma

Page 12: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.7 - Passare i vettori alle funzioni (1/4)

• Passare i vettori come parametri di funzioni– In C, il metodo di default di passaggio dei parametri è per valore

• Dentro la funzione si usa/modifica una copia locale della variabile passata

– I vettori fanno eccezione, sono passati automaticamente per riferimento• Si passa il loro vero indirizzo e non una copia del loro contenuto• Modifiche del vettore nella funzione si riflettono anche all’esterno perché

vanno a modificare le locazioni di memoria originali dell’array

– Il nome del vettore rappresenta l’indirizzo in memoria del primo elemento• Quindi la funzione sa sempre dove il vettore è memorizzato• Essendo ogni vettore costituito da celle contigue, basta conoscere la posizione

della prima perché siano note le posizioni di tutti i suoi elementi

– Sintassi: si specifica il nome del vettore senza parentesi

int MyArray[ 24 ];

MyFunction(MyArray, 24 );• Di solito, alla funzione si passa anche la dimensione del vettore

• Va passata la dimensione se nel prototipo/definizione è richiesta

• E’ richiesta quando viene usata dentro la funzione (in pratica quasi sempre)

Page 13: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.7 - Passare i vettori alle funzioni (2/4)

• Esiste un modo per passare un intero vettore per valore– Si deve anteporre parola chiave const al tipo del parametro

presente nella definizione della funzione

• Passare gli elementi dei vettori come parametri di funzioni– Gli elementi sono invece passati per valore, come qualsiasi altra

variabile– Ancora una volta, la funzione lavora su una copia dell’elemento originale

• Le modifiche sul parametro dentro la funzione non hanno effetto sull’originale

– Sintassi: MyFunction2(MyArray[3]);

• Sintassi nel prototipo della funzione funzione void ModifyArrays(int b[], int DimensioneVettore);– Il nome del vettore va seguito da [] proprio per indicare che è un vettore– Nel prototipo, come al solito si possono omettere i nomi dei parametri

• int b[] potrebbe semplicemente essere int []• int DimensioneVettore potrebbe semplicemente essere int

– Nella definizione, come al solito invece i nomi dei parametri vanno messi

Page 14: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.7 - Passare i vettori alle funzioni (3/4)

1 /* Fig. 6.13: fig06_13.c - Passare alle funzioni vettori/elementi */

2 #include <stdio.h>3 #define SIZE 545 void modificaVettore( int [], int ); 6 void modificaElemento( int );78 int main(){

9 int a[ SIZE ] = { 0, 1, 2, 3, 4 }, i; 1011 printf( "Effetti del passare un intero vettore per riferimento:"12 "\n\nI valori del vettore originale sono:\n" );13 for ( i = 0; i <= SIZE - 1; i++ ) printf( "%3d", a[ i ] );

14 printf( "\n" );15 modificaVettore( a, SIZE ); /* passaggio per riferimento */16 printf( “I valori del vettore modificato sono:\n" );

17 for ( i = 0; i <= SIZE - 1; i++ )18 printf( "%3d", a[ i ] );19 printf( "\n\n\nEffetti del passare un elemento di un vettore "20 “per valore:\n\nIl valore di a[3] è %d\n", a[ 3 ] );21 modificaElemento( a[ 3 ] ); /* passaggio per valore */22 printf( “Il valore di a[ 3 ] è %d\n", a[ 3 ] );23 return 0;

24 }

1. Dichiarazione delle funzioni

2. Passa il vettore

ad una funzione

3. Passa un elemento

ad una funzione

L’intero vettore passato per chiamata per riferimento e può essere modificato

L’elemento del vettore passato attraverso una chiamata per valore e non può essere modificato

Page 15: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.7 - Passare i vettori alle funzioni (4/4)

25

26 void modificaVettore( int b[], int size ){

27 int j;

28

29 for ( j = 0; j <= size - 1; j++ ) b[ j ] *= 2;

30 }

31

32 void modificaElemento( int e ){

33 printf( “Il valore in modifyElement è %d\n", e *= 2 );

34 }

Effetti del passare un intero vettore per riferimento: I valori del vettore originale sono: 0 1 2 3 4I valori del vettore modificato sono: 0 2 4 6 8 Effetti del passare un elemento di un vettore per valore: Il valore di a[3] è 6Il valore in modificaElemento è 12Il valore di a[3] è 6

4. Definizioni

delle funzioni

Visualizzazione del programma

Page 16: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.8 - Ordinare i vettori

• L’ordinamento di dati– E’ un’operazione molto importante e frequente nelle applicazioni– Molto spesso le organizzazione devono ordinare dati

• E in genere devono ordinare grosse quantità di dati– Esistono molti algoritmi di ordinamento dei dati, ma ne vedremo uno solo

• Bubble Sort (ordinamento a bolle) – E’ un algoritmo di ordinamento che effettua numerose passate del vettore

• Passata significa scansione dell’intero vettore con accesso ad ogni elemento• Alla fine di ogni passata si otterrà un ordinamento parziale intermedio

– Ad ogni passata, si confrontano coppie successive di elementi• Se i 2 dati sono già in ordine (o sono uguali), non si attua nessun cambiamento• Se non sono in ordine, i 2 elementi vengono scambiati

– Esempio (ordinamento crescente): Vettore originale: 3 4 2 6 7 Passata 1: 3 2 4 6 7 Ha scambiato la coppia (4,2) Passata 2: 2 3 4 6 7 Ha scambiato la coppia (3,2)

• Gli elementi più piccoli/leggeri pian piano emergono (scendono di posizione)

– Su N dati, fa sempre N-1 confronti ad ogni passata e in totale N-1 passate

• Se il vettore è già ordinato con meno di N-1 passate, le fa tutte comunque

Page 17: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(1/7)

• Media: è il valor medio calcolato su una serie di dati– Si ottiene dalla somma degli elementi del vettore diviso il numero di elementi

– 1, 2, 3, 4, 5, 6 , 7, 8, 9

La media su questi dati è 5

• Mediana: è il numero nel mezzo di una sequenza ordinata– Si ordina il vettore e si prende l’elemento in posizione centrale (dimensione/2)

– 1, 2, 3, 4, 5

La mediana su questi dati è 3

• Moda: è il numero che ricorre più frequentemente nella serie– 1, 1, 1, 2, 3, 3, 4, 5

La moda su questi dati è 1

Page 18: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(2/7)1 /* Fig. 6.16: fig06_16.c - Calcola media, mediana e moda dei dati */

2 #include <stdio.h>3 #define SIZE 9945 void trovaMedia( const int [] );6 void trovaMediana( int [] );7 void trovaModa( int [], const int [] ) ;8 void bubbleSort( int [] );9 void stampaVettore( const int [] );1011 int main(){

12 int frequenze[10] = { 0 };13 int vettoreDati[SIZE] = 14 { 6, 7, 8, 9, 8, 7, 8, 9, 8, 9, 7, 8, 9, 5, 9, 8, 7, 8, 7, 8,

15 6, 7, 8, 9, 3, 9, 8, 7, 8, 7, 7, 8, 9, 8, 9, 8, 9, 7, 8, 9,

16 6, 7, 8, 7, 8, 7, 9, 8, 9, 2, 7, 8, 9, 8, 9, 8, 9, 7, 5, 3,

17 5, 6, 7, 2, 5, 3, 9, 4, 6, 4, 7, 8, 9, 6, 8, 7, 8, 9, 7, 8,18 7, 4, 4, 2, 5, 3, 8, 7, 5, 6, 4, 5, 6, 1, 6, 5, 7, 8, 7 };

1920 trovaMedia( vettoreDati );21 trovaMediana( vettoreDati );22 trovaModa( frequenze, vettoreDati );23 return 0;24 }

1. Prototipi delle funzioni

2. Inizializza i vettori

3. Chiama le funzioni per il calcolo di media, mediana e moda

Page 19: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(3/7)

4. Definizione della funzione

che calcola la media

5. Calcolo della media

6. Stampa della media

7. Definizione della funzione

che calcola la mediana

8. Chiama la funzione che

stampa l’array originale

9. Chiama la funzione che

ordina l’array

10. Chiama la funzione che

stampa l’array ordinato

11. Visualizza l’elemento in posizione SIZE/2

2526 void trovaMedia( const int vettore[] ){

27 int j, totale = 0;2829 printf( "%s\n%s\n", "Media", "********" );

30 for ( j=0; j<=SIZE-1; j++ ) totale += vettore[j];

31 printf( “La media è uguale alla somma totale degli elementi"32 “\ndiviso per il numero di elementi ( %d ).\n"33 “Qui la media vale: %d / %d = %.4f\n\n“,

34 SIZE, totale, SIZE, (double) totale / SIZE );35 }3637 void trovaMediana( int vettore[] ){

38 printf( "\n%s\n%s\n%s", "Mediana", "********",

39 “Il vettore con i dati non ordinati è:" );40 stampaVettore( vettore );41 bubbleSort( vettore );42 printf( "\n\nIl vettore ordinato è:" );43 stampaVettore( vettore );44 printf( "\n\nLa mediana è l’elemento %d del vettore "45 "ordinato.\nQui la mediana vale: %d\n\n",46 SIZE / 2, SIZE, vettore[SIZE/2] );

47 }

48

Page 20: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(4/7)12. Definizione della

funzione che calcola la moda

13. Ciclo di incremento dei

contatori delle occorrenze,

che son dati dagli elementi

del vettore delle frequenze

14. Ad ogni giro incrementa il

contatore che si trova in

posizione pari al dato preso dal vettore

15. Stampa un istogramma con

gli asterischi che indicano

il numero di occorrenze di

ogni dato

16. Funziona perchè si usa

l’array delle frequenze dalla

seconda posizione in poi,

saltando l’indice 0

49 void trovaModa( int freq[], const int vettore[] ){50 int dato, j, h, maxFreq = 0, moda = 0;

51

52 printf( "%s\n%s\n", "Moda", "********" );

53 for ( dato=1; dato<=9; dato++ ) freq[dato] = 0;54 for ( j=0; j<=SIZE-1; j++ ) ++freq[ vettore[j] ];

55 printf( "%s%11s%19s\n\n%54s\n%54s\n\n",

56 “Elemento", "Frequenza", “Istogramma",

57 "1 1 2 2", "5 0 5 0 5" );58 for ( dato=1; dato<=9; dato++ ){

59 printf( "%8d%11d ", dato, freq[dato] );

60 if ( freq[dato] > maxFreq ){

61 maxFreq = freq[dato];

62 moda = dato;

63 }

64 for ( h=1; h<=freq[dato]; h++ )

65 printf( "*" );66 printf( "\n" );

67 }

68 printf( “La moda è l’elemento più ricorrente nel vettore.\n"

69 “Qui la moda è %d che nel vettore è presente ben"

70 " %d volte.\n", moda, maxFreq );

71 }

La stampa degli asterischi dipende dal valore di freq[]

Da notare che l’elemento di freq[] è sempre un valore di un elemento di vettore[]

Page 21: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(5/7)

17. Definizione della funzione

che ordina il vettore

18. Ciclo per fare le SIZE-1

passate del vettore

18. Ciclo interno per fare i

SIZE-1 confronti per ogni

passata del vettore

19. Usa una variabile apposta

per salvare uno dei due

valori da scambiare, in

modo da non perderlo

nello scambio

20. Definizione della funzione

che stampa il vettore

72

73 void bubbleSort( int vettore[] ){

74 int pass, j, temp;

75

76 for ( pass=1; pass<=SIZE-1; pass++ )77 for ( j=0; j<=SIZE-2; j++ )

78 if ( vettore[ j ] > vettore[ j + 1 ] ){

79 temp = vettore[ j ];

80 vettore[ j ] = vettore[ j + 1 ];

81 vettore[ j + 1 ] = temp;

82 }

83 }

84

85 void stampaVettore( const int vettore[] ){86 int j;

87

88 for ( j=0; j<=SIZE-1; j++ ){89 if ( j % 20 == 0 ) printf( "\n" );

90 printf( "%2d", vettore[ j ] );

91 }

92 }

Bubble sort: se gli elementi sono fuori ordine, li scambia.

Page 22: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(6/7)Media********La media è uguale alla somma totale degli elementi diviso per il numero di elementi (99). Qui la media vale: 681 / 99 = 6.8788 Mediana********Il vettore con i dati non ordinati è:7 8 9 8 7 8 9 8 9 7 8 9 5 9 8 7 8 7 8 6 7 8 9 3 9 8 7 8 7 7 8 9 8 9 8 9 7 8 9 6 7 8 7 8 7 9 8 9 2 7 8 9 8 9 8 9 7 5 3 5 6 7 2 5 3 9 4 6 4 7 8 9 6 8 7 8 9 7 8 7 4 4 2 5 3 8 7 5 6 4 5 6 1 6 5 7 8 7 Il vettore ordinato è: 1 2 2 2 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 La mediana è l’elemento 49 del vettore ordinato.Qui la mediana vale: 7

Visualizzazionedel programma

Page 23: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.9 - Caso di studio: calcolare media, mediana e moda usando i vettori

(7/7)Mode********Elemento Frequenza Istogramma  1 1 2 2 5 0 5 0 5  1 1 * 2 3 *** 3 4 **** 4 5 ***** 5 8 ******** 6 9 ********* 7 23 *********************** 8 27 *************************** 9 19 *******************La moda è l’elemento più ricorrente nel vettore.Qui la moda è 8 che nel vettore è presente ben 27 volte.

Visualizzazionedel programma

Page 24: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.10 - Ricerca nei vettori: ricercalineare e ricerca binaria (1/2)

• Cercare un valore chiave in un vettore– Si può trovare il valore chiave con algoritmi di ricerca lineare o binaria

• Ricerca lineare– Scandisce tutto il vettore confrontando ogni elemento col valore chiave

• Prosegue la scansione e fa confronti finchè non trova il valore chiave

– E’ un algoritmo molto semplice, utile per vettori piccoli e disordinati• Ha complessità lineare, ovvero nel caso peggiore richiede N confronti, su un

vettore di N elmenenti

• Ricerca binaria – E’ un algoritmo utilizzabile solo su vettori già ordinati– Si confronta l’elemento di mezzo (posizione N/2) del vettore con la chiave

• Se sono uguali, allora il valore voluto è stato trovato• Se chiave < mezzo, cerca allo stesso modo nella sola prima metà del vettore • Se chiave > mezzo, cerca allo stesso modo nella sola seconda metà del vettore• Si continua a ripetere questa strategia su vettori man mano sempre più piccoli

con la certezza che il valore chiave non è mai nelle parti di vettore scartate

– Molto veloce, fa al massimo P passi, dove P è l’intero superiore a log (N)• Per un vettore di 30 elementi servono al massimo 5 passi, perchè 5 > log (30)

2

2

Page 25: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.10 - Ricerca nei vettori: ricercalineare e ricerca binaria (2/2)

• Funzione di ricerca lineare

• Funzione di ricerca binaria (avendo l’array già ordinato)1 int ricercaBinaria( const int vettore[], int chiave, int size ){2 int posMin = 0, posMax = size-1, posMedia;

3 while (posMin <= posMax ){ /* Ad ogni giro, l’array è ridotto */

6 else if ( vettore[posMedia] > chiave ) posMax = posMedia - 1;7 else posMin = posMedia + 1;

8 } /* Ritorna la posizione del valore trovato */

10 }

4 posMedia = (posMin + posMax ) / 2; 5 if ( vettore[posMedia] = = chiave ) return posMedia; /* Trovato! */

9 return -1; /* Valore chiave non trovato */

1 int RicercaLineare( const int vettore[], int chiave, int size ){

3 for (i=0; i<size; i++ ){

5 } /* Ritorna la posizione del valore trovato */

6 return -1; /* Valore chiave non trovato */

7 }

4 if ( vettore[i] == chiave ) return i; /* Trovato! */

2 int i;

Page 26: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.11 - Vettori multidimensionali (1/6)

• Vettori multidimensionali – Implementano tabelle con righe e colonne (vettore m per n )

– Si accede agli elementi specificando indice di riga e di colonna (matrici) printf( "%d", b[ 0 ][ 1 ] );

– Per il resto, i loro elementi vanno trattati come quelli di normali vettori

– Si può anche ricavare l’array monodimensionale di una riga della matrice int b[] = a[1]; Ora b contiene i valori in a[1][0], a[1][1], a[1][2], a[1][3]

• Inizializzazione int c[ 2 ][ 2 ] = { { 1, 2 }, { 3, 4 } }; – Gli inizializzatori sono raggruppati per riga tra { } più interne

– Tutti gli elementi non inizializzati assumono valore 0 come al solito int c[ 2 ][ 2 ] = { { 1 }, { 3, 4 } };

Riga 0

Riga 1

Riga 2

Colonna 0 Colonna 1 Colonna 2 Colonna 3a[0][0]

a[1][0]

a[2][0]

a[0][1]

a[1][1]

a[2][1]

a[0][2]

a[1][2]

a[2][2]

a[0][3]

a[1][3]

a[2][3]

Page 27: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.11 - Vettori multidimensionali (2/6)

• Passare le matrici come parametri – Nel prototipo e nella definizione di funzioni, si deve sempre specificare la

dimensione relativa alle colonne in modo esplicito int funzione1( int [][ SIZE ], int, int ); int funzione1( int matrice1[ ][ SIZE ], int righe, int colonne){ …. }

– Come per i normali vettori, la matrice è passata di default per riferimento– Se si vuole passare la matrice per valore, si deve usare const int funzione1( const int [][ SIZE ], int, int );

– Si può passare anche un’intera riga di una matrice, mai una colonna funzione( matrice[ riga ], SIZE );

• Esempio d’uso classico: i menu testuali char menuOperazioni [4][50]={ {"1) Carica array con numeri casuali"}, {"2) Ricerca del massimo"}, {"3) Calcola la media"}, {"0) Esci dal programma"} };

– Attenzione ai limiti del vettore, la dimensione delle colonne deve essere sufficiente a contenere la stringa più lunga del menu

Page 28: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.11 - Vettori multidimensionali (3/6)

1 /* Fig. 6.22: fig06_22.c - Esempio di matrice */

2 #include <stdio.h>3 #define STUDENTI 34 #define ESAMI 456 int minimo( const int [][ ESAMI ], int, int );7 int massimo( const int [][ ESAMI ], int, int );8 double media( const int [], int );9 void stampaArray( const int [][ ESAMI ], int, int );1011 int main(){13 int studente;14 const int votiStudenti[ STUDENTI ][ ESAMI ] = 15 { { 77,68,86,73 }, { 96,87,89,78 }, { 70,90,86,81 } };1617 printf( “Il vettore dei voti è:\n" );18 printArray( votiStudenti, STUDENTI, ESAMI );19 printf( "\n\nIl voto più basso è: %d\nIl voto più alto è: %d\n",20 minimo( votiStudenti, STUDENTI, ESAMI ),21 massimo( votiStudenti, STUDENTI, ESAMI ) );22 for ( studente=0; studente<=STUDENTI-1; studente++ )23 printf( “Il voto medio per lo studente %d è %.2f\n", 24 studente, media(votiStudenti[studente], ESAMI ) ); 25 return 0;26 }

1. Prototipi delle funzioni

2. Inizializzazione del vettore bidimensionale

3. Chiama la funzione che stampa la matrice

4. Stampa il voto più alto e il più basso tra tutti gli esami/studenti chiamando le funzioni per cercare tali voti

5. Stampa la media degli studenti chiamando la funzione che le calcola

Ciascuna riga è un particolare studente e ogni colonna dà i suoi voti negli esami

Page 29: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.11 - Vettori multidimensionali (4/6)

2728 /* Cerca il voto minimo nel vettore */29 int minimo( const int voti[][ESAMI], int alunni, int risultati ){

30 int i, j, votoMinimo = 100;3132 for ( i=0; i<=alunni-1; i++ )33 for ( j=0; j<=risultati-1; j++ )34 if ( voti[i][j] < votoMinimo ) votoMinimo = voti[i][j];

35 return votoMinimo;36 }3738 /* Cerca il voto massimo */39 int massimo( const int voti[][ESAMI], int alunni, int risultati ){ 40 int i, j, votoMassimo = 0;4142 for ( i=0; i<=alunni-1; i++ )43 for ( j=0; j<=risultati-1; j++ )44 if ( voti[i][j] > votoMassimo )45 votoMassimo = voti[i][j];

46 return votoMassimo;47 }48

6. Scandisce la matrice e se trova un valore più piccolo del minimo corrente questo diventa il nuovo valore minimo

7. Scandisce la matrice e se trova un valore più grande del massimo corrente questo diventa il nuovo valore massimo

Page 30: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.11 - Vettori multidimensionali (5/6)

66 }

51 int i, totale = 0;5253 for ( i=0; i<=risultati-1; i++ ) totale += voti[i];

54 return (double) totale / risultati;55 }

5657 /* Visualizza questo vettore */

58 void stampaArray(const int voti[][ESAMI], int alunni, int risultati){ 59 int i, j;6061 printf( “ [0] [1] [2] [3]" );

62 for ( i=0; i<=alunni-1; i++ ){

63 printf( "\nVOTI[%d] ", i );

64 for ( j=0; j<=risultati-1; j++ ) printf( "%-5d", voti[i][j] );

65 }

49 /* Determina il voto medio per un particolare studente */50 double media(const int voti[], int risultati){

8. Scandisce il vettore passato che contiene un riga della matrice (quindi i soli voti di un certo studente) per calcolarne la media

9. Ciclo che stampa a video la matrice dei voti di ogni studente

Page 31: 2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario 6.1 - Introduzione 6.2 - Vettori 6.3 - Dichiarazione di vettori 6.4

2000 Prentice Hall, Inc. All rights reserved.

6.11 - Vettori multidimensionali (6/6)

Il vettore dei voti è: [0] [1] [2] [3]VOTI[0] 77 68 86 73 VOTI[1] 96 87 89 78 VOTI[2] 70 90 86 81 Il voto più basso è: 68Il voto più alto è: 96La media dei voti per lo studente 0 è 76.00La media dei voti per lo studente 1 è 87.50La media dei voti per lo studente 2 è 81.75

Visualizzazione del programma