Corso di Laurea Ingegneria Informatica Fondamenti di Informatica Dispensa 17 Array e Oggetti A. Miola Gennaio 2012 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 1 Contenuti Array paralleli Array e oggetti Ricerca sequenziale Ricerca binaria Fusione di sequenze ordinate http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 2 Array paralleli Un insieme di array paralleli è un insieme formato da due o più array della stessa lunghezza, in cui gli elementi che occupano una stessa posizione formano un gruppo correlato di dati come nel caso degli array nomi e voti nel problema degli studenti da promuovere nomi voti 0 Rossi 0 8.1 1 Verdi 1 3.2 2 Bianchi 2 5.2 3 Gialli 3 5.6 19 Neri 19 8.5 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti dati sullo studente Bianchi individuati nei due array dallo stesso indice 2 3 Array e oggetti Gli elementi di un array possono essere dei riferimenti a oggetti il problema degli studenti da promuovere può essere risolto usando un array di oggetti, in cui ciascun elemento è un oggetto che rappresenta i dati di uno studente la relativa valutazione è una alternativa che può essere preferita agli array paralleli http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 4 Un array di oggetti vs v0 nome = Rossi voto = 8.1 0 1 2 3 v1 nome = Verdi voto = 3.2 19 v2 nome = Bianchi voto = 5.2 v3 nome = Gialli voto = 5.6 … v19 nome = Neri voto = 8.5 oggetto dati per lo studente Bianchi http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 5 La classe Valutazione /* Un oggetto Valutazione rappresenta il nome * di uno studente e la votazione che ha ricevuto. */ class Valutazione { /* Il nome dello studente. */ private String nome; /* La votazione ricevuta dallo studente. */ private double voto; /* Crea una nuova Valutazione, dati nome e votazione. */ public Valutazione(String nome, double voto) { this.nome = nome; this.voto = voto; } /* Restituisce il nome dello studente. */ public String getNome() { return nome; } /* Restituisce il voto ottenuto dallo studente. */ public double getVoto() { return voto; } } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 6 Il problema degli studenti . . . final int NUMERO_STUDENTI = 20; Valutazione[] vs; // numero degli studenti // valutazioni degli studenti String nome; // nome di uno studente double voto; // votazione ottenuta da uno studente int i; // indice per la scansione di vs double sommaVoti; // somma dei voti double soglia; // soglia per la promozione /* crea l'array per le valutazioni degli studenti */ vs = new Valutazione[NUMERO_STUDENTI]; /* leggi nomi e votazioni dei cinque studenti */ ... stampa un messaggio ... for (i=0; i<NUMERO_STUDENTI; i++) { /* leggi nome e votazione dell'i-esimo studente */ nome = Lettore.in.leggiString(); voto = Lettore.in.leggiDouble(); /* crea la valutazione per l'i-esimo studente */ vs[i] = new Valutazione(nome,voto); } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 7 . . . Il problema degli studenti /* calcola la soglia per la promozione */ sommaVoti = 0; for (i=0; i<NUMERO_STUDENTI; i++) sommaVoti += vs[i].getVoto(); soglia = (2./3.) * (sommaVoti/NUMERO_STUDENTI); /* stampa l'elenco degli studenti da promuovere */ ... stampa un messaggio ... for (i=0; i<NUMERO_STUDENTI; i++) { /* verifica se l'i-esimo studente è stato promosso */ if (vs[i].getVoto() >= soglia) System.out.println(vs[i].getNome() + " " + vs[i].getVoto()); } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 8 Esercizi Scrivere un metodo che, dato un numero naturale N, crea e restituisce un array di N oggetti Rettangolo creati in modo casuale Scrivere un metodo che, ricevendo come parametro un array di oggetti Rettangolo, calcola e restituisce il rettangolo di area massima Scrivere un metodo che, ricevendo come parametro un array di oggetti Rettangolo, calcola e restituisce la coppia di rettangoli la cui intersezione ha area massima http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 9 Esercizi Data la classe Libro per rappresentare oggetti libro con il nome dell’autore, il titolo e il numero di pagine e con i relativi metodi d’istanza scrivere un metodo che, ricevendo come parametro un array di oggetti Libro, calcola e restituisce un array di oggetti Libro dello stesso autore scrivere un metodo che, ricevendo come parametro un array di oggetti Libro, calcola e restituisce l’oggetto Libro con il massimo numero di pagine http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 10 Esercizi Data la classe Auto per rappresentare oggetti automobile con il nome della marca, il nome del modello, la targa e l’anno di immatricolazione e con i relativi metodi d’istanza scrivere un metodo che, ricevendo come parametro un array di oggetti Auto, calcola e restituisce un array di oggetti Auto della stessa marca e dello stesso modello scrivere un metodo che, ricevendo come parametro un array di oggetti Auto, calcola e restituisce l’oggetto Auto più vecchia http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 11 Ricerca di un elemento in un array Descrizione del problema dato un array a di elementi di tipo T e un valore chiave di tipo T verificare se l’array a contiene un elemento uguale a chiave se a contiene almeno un elemento uguale a chiave, allora deve essere calcolato e restituito l’indice (ovvero, la posizione) di uno degli elementi di a tra quelli uguali a chiave altrimenti, deve essere restituito il valore -1 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 12 Il problema della ricerca in un array Nell’esecuzione di una operazione di ricerca in un array sono possibili diverse situazioni a 5 4 12 9 0 2 16 2 0 1 2 3 4 5 6 7 se il valore chiave è uguale a 16, l’array a contiene un solo elemento uguale a chiave in questo caso va restituito l’indice 6 se chiave è uguale a 6, l’array a non contiene nessun elemento uguale a chiave in questo caso va restituito il valore –1 se chiave è uguale a 2, l’array a contiene più di un elemento uguale a chiave può essere restituito indifferentemente l’indice 5 oppure 7 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 13 Spazio di ricerca Nella ricerca di una chiave in un array, in ogni momento del processo di ricerca, gli elementi dell’array sono partizionati in due insiemi: un insieme è composto dagli elementi che sono già stati esaminati l’altro insieme è composto dagli elementi ancora da esaminare Per spazio di ricerca si intende la porzione dell’array che è candidata a contenere la chiave della ricerca http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 14 Spazio di ricerca Lo spazio di ricerca varia in modo dinamico durante l’esecuzione dell’algoritmo di ricerca inizialmente lo spazio di ricerca contiene tutti gli elementi dell’array la chiave viene confrontata solo con elementi dello spazio di ricerca ogni confronto tra la chiave e un elemento dello spazio di ricerca può trovare l’elemento e terminare la ricerca, oppure ridurre lo spazio di ricerca Solitamente lo spazio di ricerca è una porzione contigua dell’array, delimitata da un indice o da una coppia di indici http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 15 Spazio di ricerca nella ricerca sequenziale Nella ricerca sequenziale lo spazio di ricerca si riduce sempre di una componente finché non viene trovato l’elemento. 7 34 0 9 2 7 22 12 16 5 2 7 34 0 9 7 2 22 12 16 5 2 7 2 22 12 16 5 2 2 22 12 16 5 2 7 34 0 9 7 34 0 9 http://www.dia.uniroma3.it/~java/fondinf/ 7 Array e Oggetti 16 Ricerca sequenziale: algoritmo Input: Output: a: array con elementi di tipo T, chiave: elemento di tipo T indice: intero indice della componente dell’array in cui si trova l’elemento cercato (se esiste), -1 se non esiste Algoritmo • Gli elementi di a vengono analizzati, in sequenza, confrontandoli con l’elemento chiave da cercare, finché non viene trovato un elemento uguale a chiave • Se sono stati esaminati tutti gli elementi di a e non è stato trovato nessun elemento uguale a chiave la ricerca non ha avuto successo La ricerca è sequenziale, nel senso che gli elementi dell’array vengono scanditi in sequenza, uno dopo l’altro http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 17 Ricerca sequenziale: codifica /* Verifica se l’array a contiene un elemento uguale a * chiave, e restituisce la posizione della prima * occorrenza di chiave in a, oppure -1. */ public static int ricercaSequenziale(int[] a, int chiave){ // pre: a!=null int indice; // posizione di chiave in a int i; // indice per la scansione di a boolean trovato; // vero se l’el. e’ stato trovato /* scandisce gli elementi di a, alla ricerca della * prima occorrenza di chiave in a */ indice = -1; trovato = false; i = 0; while (i < a.length && !trovato){ if (a[i] == chiave) { indice = i; trovato = true;} i++; } return indice; } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 18 Ricerca sequenziale: analisi dei costi Ipotesi: l’array ha n elementi Caso peggiore: L’elemento non esiste nella sequenza Devo confrontare chiave con tutti gli elementi dell’array n confronti Caso migliore: L’elemento viene trovato al primo confronto 1 confronto In generale L’elemento esiste e si trova in posizione p < n p+1 confronti http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 19 Ricerca in un array ordinato Consideriamo il problema della ricerca in un array ordinato in particolare, ordinato in modo non decrescente per i = 0..a.length-1, a[i] <= a[i+1] 0 1 3 4 7 9 12 16 22 34 0 1 2 3 4 5 6 7 8 9 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 20 Ricerca binaria Inizialmente lo spazio di ricerca è composto da tutti gli elementi dell’array Finché non è stato trovato un elemento dell’array uguale alla chiave (e comunque lo spazio di ricerca è non vuoto) confronta la chiave con l’elemento centrale dello spazio di ricerca se la chiave è uguale all’elemento centrale dello spazio di ricerca, allora la ricerca termina con esito positivo se invece la chiave è maggiore dell’elemento centrale dello spazio di ricerca, rimuovi dallo spazio di ricerca l’elemento centrale e tutti quelli alla sua sinistra se invece la chiave è minore dell’elemento centrale dello spazio di ricerca, rimuovi dallo spazio di ricerca l’elemento centrale e tutti quelli alla sua destra http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 21 Ricerca binaria – successo 7 0 1 3 4 7 s=0 9 12 16 22 34 c=5 d=10 7 0 1 s=0 3 4 7 c=2 9 12 16 22 34 12 16 22 34 d=5 7 0 1 3 4 7 9 s=3 c=4 d=5 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 22 Ricerca binaria – fallimento 18 0 1 3 4 7 s=0 9 12 16 22 34 c=5 d=10 18 0 1 3 4 7 9 12 16 s=6 22 34 c=8 d=10 18 0 1 3 4 7 9 12 16 22 34 s=6 c=7 d=8 0 1 3 4 7 9 12 16 22 34 s=d=8 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 23 Spazio di ricerca nella ricerca binaria Nella ricerca binaria lo spazio di ricerca è formato da insieme di elementi contigui di a, delimitato mediante una coppia di indici, sinistra e destra sinistra è l’indice del primo elemento dello spazio di ricerca (ovvero, quello più a sinistra) destra è l’indice del primo elemento oltre lo spazio di ricerca lo spazio di ricerca è perciò composto dagli elementi di indice tra sinistra (incluso) e destra (escluso) l’algoritmo usa anche una variabile centro per indicare l’elemento centrale dello spazio di ricerca ad ogni iterazione, centro viene scelto pari a (sinistra+destra)/2 N.B.: ( / denota la divisione tra interi) http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 24 Ricerca binaria: codifica /* Ricerca chiave nell'array a ordinato in modo * non descrescente, restituendo l'indice di un * elemento di a uguale a chiave (oppure -1). */ public static int ricercaBinaria(int[] a, int chiave) { // pre: a!=null && a è ordinato in modo non decrescente int posizione; // posizione di un elemento di a // uguale a chiave, se esiste int sinistra; // indice del primo elemento dello // spazio di ricerca int destra; // indice del primo elemento oltre // lo spazio di ricerca int centro; // indice dell'elemento centrale // dello spazio di ricerca boolean trovato; // vero se l’elemento viene trovato http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 25 Ricerca binaria: codifica /* inizialmente lo spazio di ricerca comprende * tutti gli elementi di a */ sinistra = 0; destra = a.length; trovato = false; /* cerca l'indice di un elemento di a uguale * a chiave, se esiste, mediante la ricerca binaria */ posizione = -1; while (sinistra<destra && !trovato) { centro = (sinistra+destra)/2; if (a[centro]==chiave){ // trovato trovato = true; posizione = centro; } else if (a[centro]>chiave) // continua a sinistra destra = centro; else // continua a destra sinistra = centro+1; } return posizione; } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 26 Analisi dei costi della ricerca binaria Ipotesi: n è una potenza di due n = 2h 0 1 3 4 7 9 12 16 Ad ogni iterazione lo spazio di ricerca si dimezza Confronto spazio di ricerca 1° …………………… n 2° …………………… n / 2 3° …………………… n / 22 …. …. h+1-esimo ………... n / 2h = 1 Quanti confronti? h+1, ma h = log2 n, quindi log2 n + 1 confronti http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 27 Esempio Cerchiamo il valore 1 1 1° confronto 0 2 3 4 7 9 12 16 4 7 9 12 16 1 2° confronto 0 2 3 1 3° confronto 0 2 3 4 7 9 12 16 2 3 4 7 9 12 16 1 4° confronto 0 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 28 Esercizi Scrivere un metodo che, dati due array di interi, non necessariamente della stessa dimensione, ciascuno dei quali è ordinato in modo crescente, calcola il numero di elementi comuni ai due array A 2 7 11 21 48 89 B 7 11 15 21 42 45 Discutere il costo dell’algoritmo implementato, nel caso peggiore http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 29 Esercizi Descrivere l’applicazione dell’algoritmo di ricerca binaria con riferimento al seguente array 0 1 3 4 7 9 12 16 22 34 0 1 2 3 4 5 6 7 8 9 usando come chiave i valori 0, -5, 22 e 44 descrivere, in particolare, l’evoluzione dello spazio di ricerca Scrivere un metodo, basato sulla ricerca binaria, che calcola la posizione del primo elemento di un array ordinato uguale alla chiave della ricerca http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 30 Esercizio Scrivere un metodo int[ ] inserisci(int[ ] a, int v), in cui a è un array ordinato in modo non decrescente, che crea e restituisce un nuovo array che contiene l’elemento v insieme a tutti gli elementi di a, ed è ancora ordinato in modo non descrescente ad esempio, inserisci(new int[ ] { 3, 5, 6, 8 }, 4) deve restituire l’array { 3, 4, 5, 6, 8 } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 31 Fusione di sequenze ordinate La fusione di due sequenze ordinate è una operazione che date due sequenze a e b ordinate in modo non decrescente costruisce una nuova sequenza s che contiene tutti gli elementi di a e b - la cui lunghezza è quindi uguale alla somma delle lunghezze di a e b - ed è ordinata in modo non decrescente a 5 12 26 34 s b 6 8 5 6 8 12 21 26 34 21 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 32 Strategia di fusione Assegno gli elementi di s — uno alla volta, in sequenza individuo la posizione di s in cui inserire il prossimo elemento di a o di b • l’indice iniziale di s vale 0 il prossimo elemento (di a o di b) viene scelto tra l’elemento più piccolo di a e quello più piccolo di b tra quelli che non sono ancora stati inseriti in s http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 33 Algoritmo di fusione L’algoritmo per la fusione di array ordinati gestisce tre indici l’indice ia del più piccolo elemento di a tra quelli che non sono ancora stati inseriti in s l’indice ib del più piccolo elemento di b tra quelli che non sono ancora stati inseriti in s l’indice is del prossimo elemento da inserire in s • inizialmente valgono tutti 0 in modo iterativo, il prossimo elemento da inserire in s[is] viene scelto tra a[ia] e b[ib] • attenzione all’incremento degli indici http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 34 Indici nella fusione di array ia=1 a 5 12 26 34 s b 6 8 5 6 8 is=3 21 ib=2 ia=2 a 5 12 26 34 12 s b 6 8 5 6 8 12 is=4 21 ib=2 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 35 Indici nella fusione di array A un certo punto, tutti gli elementi di uno dei due array saranno stati inseriti in s ia=2 a 5 12 26 34 s b 6 8 5 6 8 12 21 is=5 21 ib=3 da questo momento in poi, l’algoritmo procede diversamente con la copia degli elementi residui dell’altro array http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 36 Implementazione della fusione . . . /* Fonde gli array a e b ordinati in modo * non decrescente in un nuovo array ordinato. */ public static int[] fusione(int[] a, int[] b) { // pre: a!=null && b!=null && // a e b ordinati in modo non decrescente int[] s; // risultato della fusione di a e b int ia, ib, is; // indici per a, b e s /* inizializzazioni */ s = new int[a.length+b.length]; ia = 0; ib = 0; is = 0; . . . segue . . . http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 37 . . . Implementazione della fusione . . . . . . segue . . . /* prima fase della fusione: inserisci da a e b */ while (ia<a.length && ib<b.length) { /* inserisci in s il più piccolo tra a[ia] e b[ib] */ if (a[ia]<b[ib]) { s[is] = a[ia]; ia++; } else { s[is] = b[ib]; ib++; } is++; } /* ora ia==a.length || ib==b.length */ . . . segue . . . http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 38 . . . Implementazione della fusione . . . segue . . . /* seconda fase della fusione: inserisci da a o b */ if (ib==b.length) /* inserisci da a: */ /*l'indice ib non serve piu': lo riutilizzo nel ciclo */ for (ib=ia; ib<a.length; ib++){ s[is] = a[ib]; is++;} else /* inserisci da b */ /*l'indice ia non serve piu': lo riutilizzo nel ciclo */ for (ia=ib; ia<b.length; ia++){ s[is] = b[ia]; is++;} /* ora la fusione è stata completata */ return s; } http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 39 Esercizio Affrontare nuovamente il seguente problema, ispirandosi all’algoritmo di fusione calcola il numero di elementi comuni a due array ordinati in modo crescente A 2 7 11 B 7 11 15 21 42 45 http://www.dia.uniroma3.it/~java/fondinf/ 21 48 89 Array e Oggetti 40 Esercizio Implementare la fusione con rimozione di duplicati ciascuna delle sequenze iniziali non contiene duplicati a 5 12 26 34 s b 5 http://www.dia.uniroma3.it/~java/fondinf/ 8 5 8 12 26 34 26 Array e Oggetti 41 Riferimenti al libro di testo Per lo studio di questi argomenti si fa riferimento al libro di testo, e in particolare ai paragrafi dal 19.6 alla fine del capitolo 19 http://www.dia.uniroma3.it/~java/fondinf/ Array e Oggetti 42