1 java/fondinf/esercizi corso di laurea ingegneria informatica fondamenti di informatica dispensa 26...
TRANSCRIPT
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 1
Corso di Laurea Ingegneria InformaticaFondamenti di Informatica
Dispensa 26
Esercizi
F. Gasparetti, C. Limongelli Maggio 2011
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 2
Verifica presenza di elementi comuni…
N1 - Date due liste di stringhe scrivere un metodo che verifichi la presenza di elementi comuni ad entrambe
La classe per le liste di stringhe:class NodoLista {
public String info;public NodoLista next;public NodoLista(String s,
NodoLista n){info = s; next = n;}
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 3
… Verifica presenza di elementi comuni…
Bisogna verificare che esiste almeno un elemento nella prima lista che è uguale ad un elemento nella seconda lista
Verifica esistenziale sulla prima listaVerifica esistenziale sulla seconda lista
Fissato un elemento della prima lista, verificare che sia presente nella seconda
Il metodo isMember verifica se una stringa s è presente in una lista l
Il metodo nodiComuni esegue la verifica sulla prima lista
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 4
Il metodo isMember
/* data una stringa e una lista verifica che la stringa sia presente in qualche nodo della lista: verfica esistenziale sulla seconda lista*/
public static booleanisMember(String s, NodoLista l){
boolean esiste;esiste = false;while (l!=null && !esiste){
if (s.equals(l.info))esiste = true;
l = l.next;}return esiste;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 5
… Verifica presenza di elementi comuni…
Verifica esistenziale sulla prima lista
public static booleannodiComuni(NodoLista l1, NodoLista l2){
boolean comune;comune = false;while (l1 != null && !comune){
if (isMember(l1.info,l2))comune = true;
l1 = l1.next;}return comune;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 6
Costruzione lista nodi comuni…
N2 - Date due liste di stringhe restituire una nuova lista che contenga gli elementi comuni ad entrambe le liste date
Algoritmo: Costruzione con un nodo generatore: Creo il primo nodo fittizio Finche’ ci sono elementi da esaminare nella prima lista
• se l’elemento che sto esaminando e’ presente nella seconda lista
allora creo un nuovo nodo che lo contiene e attacco il nuovo nodo in coda alla lista che sto costruendo
Restituisco il secondo nodo della lista costruita
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 7
public static NodoLista listaNodiComuni (NodoLista l1, NodoLista l2){NodoLista n,app;// costruzione con record generatoren = new NodoLista(null,null);app = n;while (l1 !=null){
if (isMember(l1.info,l2)){app.next = new NodoLista(l1.info,null);app = app.next;
}l1 = l1.next;
}return n.next;
}
…Costruzione lista nodi comuni…
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 8
Merge liste …
N3 - Date due liste di stringhe, ordinate in modo non decrescente, scrivere un metodo merge che effettui l’operazione di fusione restituendo una nuova lista ordinata, contenente tutti gli elementi delle due liste
L’algoritmo è identico all’algoritmo di fusione di due array ordinati, cambia solo la modialita’ di scansione delle sequenze di elementi
Il confronto tra le stringhe viene realizzato dal metodo maggiore
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 9
Il metodo per confrontare le stringhe
Invece di implementare il confronto lessicografico tra stringhe come visto in precedenza, usiamo il metodo compareTo definito nella classe String:
public static boolean maggiore(String s1, String s2){
boolean res;if (s1.compareTo(s2)<=0) // s1<=s2
res = false;else res = true;return res;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 10
… Merge liste …
public static NodoLista mergeListe(NodoLista l1, NodoLista l2){
NodoLista n,app;//per la nuova lista
n = new NodoLista(null, null);app = n;while(l1 !=null && l2 !=null)
// se l1.info <= l2.infoif (maggiore(l2.info,l1.info)){
//creo un nodo con il contenuto di l1app.next = new NodoLista(l1.info,null);app = app.next;// mi posiziono sul prossimo nodo di l1l1 = l1.next;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 11
… Merge liste …
else{ //l1.info>l2
// creo un nodo con il contenuto di l2
app.next = new NodoLista(l2.info,null);
app = app.next;
// mi posiziono sul prossimo nodo di l1
l2 = l2.next;
}
// quando termina il while una delle due liste e' null
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 12
… Merge liste
if (l1==null)while(l2!=null){
app.next = new NodoLista(l2.info,null);app = app.next;l2 = l2.next;
}elsewhile(l1!=null){
app.next = new NodoLista(l1.info,null);app = app.next;l1 = l1.next;
}return n.next;}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 13
Il metodo ricercaSequenza…
N4 - Scrivere il metodo ricercaSequenza che, date due liste di stringhe la e lb, verifichi se esiste una sequenza di elementi in la corrispondente agli elementi in lbEsempio: data la = ( A B B C D E ) e lb = ( B B C ) la
risposta dovrà essere true, mentre per la = ( A B B C D E ) e lb = ( A B C ) la risposta dovrà essere false
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 14
… Il metodo ricercaSequenza…
Considero il generico elemento della lista la come la testa della lista che esamino attualmente.
Due liste sono uguali se i primi nodi della lista la coincidono con tutti i nodi della lista lb
Esempio: la = ( A B B C D E ) e lb = ( B B C ) Se analizzo la lista la a partire da B osservo che tutti I
nodi della lista lb coincidono con i primi nodi di la
Ricorsione su la
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 15
… Il metodo ricercaSequenza…
Passo base la vuota non ho individuato la sottosequenza
Passo ricorsivo La sottosequenza viene individuata se i primi elementi di la coincidono con tutti gli
elementi di lb oppure la sottosequenza viene individuata sulla lista che
parte dal nodo successivo ad la
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 16
… Il metodo ricercaSequenza…
public static boolean ricercaSequenza(NodoLista l1, NodoLista l2){
/* verifica esistenziale */
boolean trovata;
if (l1 == null) trovata = false;
else
trovata = uguali(l1,l2) || ricercaSequenza(l1.next,l2);
return trovata;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 17
… Il metodo uguali…
Date due liste l1 e l2, verifica che i primi elementi di l1 siano uguali a tutti gli elementi di l2
Ricorsione su entrambe le liste Passo base:
Se e’ terminata la scansione di l2 allora ho esaminato con successo tutti gli elementi true
Se e’ terminata la scansione di l1 allora l1 non puo’ contenere tutti gli elementi di l2 quindi false
N.B.: I due passi base vanno necessariamente in questo ordine
Passo ricorsivo La ricerca ha successo se i primi due elementi delle liste sono
uguali e se sono uguali le liste l1.next e l2.next
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 18
… Il metodo uguali…
public static boolean uguali (NodoLista l1, NodoLista l2){
boolean sonouguali;
/*passo base */if (l2 == null) sonouguali = true;elseif (l1 == null) sonouguali = false;else/* passo ricorsivo */ sonouguali = l1.info.equals(l2.info) &&
uguali(l1.next,l2.next);
return sonouguali;}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 19
Eliminazione dei doppioni da una lista
N5 - Scrivere il metodo eliminaDoppioni che, data una lista di stringhe, restituisca una nuova lista ottenuta eliminando dalla lista data i doppioniEsempio: data elle = ( A A A B A B )
eliminaDoppioni(elle) restituisce la lista ( A B )
Tre versioni del problema Creazione della nuova lista in modo iterativo
modificando quella originale Creazione della nuova lista in modo iterativo senza
modificare quella originale (come richiesto) Creazione della lista in modo ricorsivo senza
modificare quella originale
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 20
Creazione iterativa di una lista che modifica quella originale …
Per ogni nodo l della lista Si eliminano dal resto della lista (l.next) tutti i nodi che hanno il
campo informazione uguale a l.info
Eliminazione di tutti i nodi il cui campo informazione è uguale ad una data stringa (l.info). Bisogna tenere un puntatore che referenzia il nodo precedente
a quello da eliminare
l.info non è una stringa qualsiasi, bensì la stringa contenuta nel primo nodo della lista
Il metodo elimina non passa come parametri attuali l.info e l.next, ma l.info e l. In questo modo il primo nodo – che non può essere eliminato - serve per inizializzare il puntatore al nodo precedente
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 21
…Creazione iterativa di una lista che modifica quella originale …//elimina tutte le occorrenze di s dalla lista l// il cui primo nodo contiene proprio spublic static void elimina(String s, NodoLista l){
NodoLista succ,prec;
prec = l;succ = l.next;while (succ != null){
if (s.equals(succ.info)){prec.next = succ.next;succ = prec.next;
}else {
succ = succ.next;prec = prec.next;
} } }
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 22
…Creazione iterativa di una lista che non modifica quella originale …
Il metodo elimina va applicato ad ogni nodo della lista (che via via viene modificata)
public static void eliminaTutti(NodoLista l){
NodoLista app;while (l != null){
/* elimino tutti i doppioni di l.info dal resto della lista */elimina(l.info,l);l = l.next;
}}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 23
…Creazione iterativa di una nuova lista che modifica quella originale …
Banalmente si applica il metodo eliminaTutti alla copia della lista data in input:
public static NodoLista eliminaDoppioni(NodoLista l){NodoLista n,app; //nuova lista con doppionin = new NodoLista(null,null);app = n;while (l != null){
app.next = new NodoLista(l.info,null);app = app.next;l = l.next;
}n = n.next;return eliminaTutti(n.next);
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 24
Creazione ricorsiva di una lista che non modifica quella originale …
Passo base lista vuota: tutta la lista e’ stata scandita
Passo ricorsivo: vedo se il primo elemento e' gia' presente nel resto
della lista che e’ stata creata eliminando tutti i doppioni.
se e' gia’ presente restituisco la nuova lista senza il primo elemento
altrimenti restituisco la lista nuova lista a cui e’ stato aggiunto in testa un nuovo nodo che contiene il primo elemento della lista che si sta esaminando
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 25
Creazione ricorsiva di una lista che non modifica quella originale …
public static NodoLista eliminaRIC(NodoLista l){
NodoLista app;
app = null;
if (l != null){
app = eliminaRIC(l.next);
if (!isMember(l.info,app))
app = new NodoLista(l.info,app);
}
return app;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 26
Altri esercizi
I tipi astratti Coppia, Razionale, Complesso
Rappresentazione dei tipi Coppia, Razionale,
Complesso
Rappresentazione compatta di matrici sparse
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 27
Un altro esempio: i numeri razionaliConsideriamo il tipo astratto Q dei numeri
razionali, ricordando quanto già visto nel corso circa la classe Razionale Gli elementi a/b del dominio di interesse possono
essere denotati da una coppia di numeri interi (a, b)
• a denota il numeratore della frazione, mentre b denota il denominatore
Le operazioni del tipo Q sono le usuali operazioni :Addizione, Moltiplicazione, ecc.
In effetti anche Coppia è un tipo astratto di dato che può essere opportunamente rappresentato da una classe Coppia
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 28
Il tipo astratto Coppia . . .
Il tipo astratto Coppia rappresenta il prodotto cartesiano di due domini
I valori di tale tipo sono coppie di valori presi da due domini specificati
Le operazioni associate sono semplicemente la costruzione il calcolo del valore della prima componente il calcolo del valore della seconda componente
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 29
. . . Il tipo astratto Coppia
La specifica del tipo Coppia, con i suoi domini (tra
cui quello di interesse) e le sue funzioni, è
quindi la seguente
Domini
Coppia : dominio di interesse del tipo
T1 : dominio dei valori che possono comparire come
prima componente delle coppie
T2 : dominio dei valori che possono comparire come
seconda componente delle coppie
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 30
. . . Il tipo astratto Coppia
Funzioni formaCoppia(T1 a, T2 b) Coppia
• pre: nessuna• post: RESULT è il valore corrispondente alla coppia la cui
prima componente è a e la seconda è b
primaComponente(Coppia c) T1 • pre: nessuna • post: RESULT è la prima componente della coppia c
secondaComponente(Coppia c) T2 • pre: nessuna • post: RESULT è la seconda componente della coppia c
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 31
Rappresentazione del tipo Coppia . . .
La realizzazione del tipo astratto Coppia come una classe Java Coppia è immediata Rappresentiamo i valori del tipo astratto utilizzando
due campi dati (variabili di istanza) di tipo opportuno per memorizzare le due componenti della coppia
Schema realizzativo: utilizziamo lo schema realizzativo funzionale come illustrato precedentemente
Interfaccia di classe: come visto definiamo un metodo per ciascuna delle funzioni del tipo astratto
Realizziamo la funzione formaCoppia attraverso un costruttore
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 32
. . . Rappresentazione del tipo Coppia
public class Coppia {
// rappresentazione dei valori
protected Object c1;
protected Object c2;
// realizzazione delle funzioni del tipo astratto
public Coppia (Object c1, Object c2) {
// realizza formaCoppia
this.c1 = c1;
this.c2 = c2; }
public Object primaComponente() { return c1; }
public Object secondaComponente() { return c2; }
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 33
. . . Rappresentazione del tipo Coppia
Sebbene alcune segnature non sembrano strettamente funzionali o coincidenti con le funzioni del tipo di dato astratto, come ad esempio:
Java: public Object primaComponente();
ADT: primaComponente(Coppia c) T1
lo schema realizzativo del tipo di dato astratto è funzionale poiché i metodi della classe operano sui valori del tipo astratto e non eseguono operazioni di modifica di oggetti Java (oggetti di invocazione e parametri) che rappresentano tali valori
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 34
Il tipo astratto Razionale . . .
Un numero razionale è un numero reale ottenibile come rapporto tra due numeri interi, il secondo dei quali diverso da 0. Ogni numero razionale quindi può essere espresso mediante una frazione a/b.
A questo punto possiamo definire il tipo di dato astratto Razionale riprendendo il tipo Coppia, notando che: I due domini T1 e T2 possono essere i due domini di
valori che possono assumere numeratore e denominatore del numero razionale
Le funzioni del tipo Razionale sono quelle classiche, ad esempio addizione e moltiplicazione.
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 35
. . . Il tipo astratto Razionale . . .
Domini
Razionale : dominio di interesse del tipo
T1 : dominio dei valori che può assumere il
numeratore
T2 : dominio dei valori che può assumere il
denominatore
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 36
. . . Il tipo astratto Razionale . . .
Funzioni (1 di 2) formaRazionale(T1 a, T2 b) Razionale
• pre: b non rappresenti 0• post: RESULT è il valore corrispondente al numero razionale
a/b
numeratore(Razionale q) T1 • pre: nessuna • post: RESULT è il numeratore del razionale q
denominatore(Razionale q) T2 • pre: nessuna • post: RESULT è il denominatore del razionale q
. . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 37
. . . Il tipo astratto Razionale . . .
Funzioni (2 di 2) add(Razionale q1, Razionale q2) Razionale
• pre: nessuna • post: RESULT è il numero razionale corrispondente alla
somma dei due razionali rappresentati da q1 e q2
molt(Razionale q1, Razionale q2) Razionale • pre: nessuna • post: RESULT è il numero razionale corrispondente alla
moltiplicazione dei due razionali rappresentati da q1 e q2
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 38
Rappresentazione del tipo Razionale . . .
L’implementazione della classe Razionale può essere basata su Coppia estendendo opportunamente le funzionalità di quest’ultima classe Rappresentiamo i valori del tipo astratto con oggetti
Coppia Schema realizzativo funzionale Interfaccia di classe: definiamo un metodo per
ciascuna delle funzioni del tipo astratto Realizziamo la funzione formaRazionale attraverso
un costruttore
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 39
. . . Rappresentazione del tipo Razionale
class Razionale extends Coppia { public Razionale (Long c1, Long c2){ super (c1,c2); // richiama il costruttore di Coppia }
public void simpl() { // semplifica il razionale long app, num, den; num = ((Long)(this.c1)).longValue(); den = ((Long)(this.c2)).longValue(); app = mcd(num,den); c1 = new Long(num / app); c2 = new Long(den / app); }
public String toString(){ simpl(); return primaComponente()+ "/" +secondaComponente(); } . . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 40
. . . Rappresentazione del tipo Razionale
public Razionale add(Razionale q) { long a = ((Long)c1).longValue(); long b = ((Long)c2).longValue(); long c = ((Long)q.c1).longValue(); long d = ((Long)q.c2).longValue(); return new Razionale(new Long(a*d+b*c),
new Long(b*d)); }
public Razionale mult(Razionale q) { long a = ((Long)c1).longValue(); long b = ((Long)c2).longValue(); long c = ((Long)q.c1).longValue(); long d = ((Long)q.c2).longValue(); return new Razionale(new Long(a*c),new Long(b*d));
} . . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 41
. . . Rappresentazione del tipo Razionale
private static long mcd(long x, long y){ long t,r; if ( x < y ) {/* se x < y li scambio */ t = x; x = y; y = t; } while ( y > 0 ) { r = x % y; x = y; y = r; } return x; }}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 42
. . . Rappresentazione del tipo Razionale
Le due funzioni add e molt sono state implementate con uno schema funzionale, ovvero esse non modificano gli oggetti su cui esse vengono invocate.
public Razionale add(Razionale q) {
. . .
return new Razionale(. . .);
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 43
Il tipo astratto Complesso . . .
I numeri complessi sono formati da due parti, una parte reale ed una parte immaginaria:
a + ib Ancora una volta possiamo definire il tipo di dato
astratto riprendendo il tipo Coppia, notando che: I due domini T1 e T2 possono essere i due domini di valori
che possono assumere parte reale e parte immaginaria del numero complesso
Le funzioni del tipo Complesso sono quelle classiche, ad esempio addizione, moltiplicazione, etc.
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 44
Rappresentazione del tipo Complesso. . .
Come per il Razionale, una classe che rappresenta il tipo astratto Complesso può essere basata sulle seguenti scelte: Rappresentiamo il dominio dei valori di interesse
del tipo astratto con oggetti Coppia Schema realizzativo funzionale Interfaccia di classe: definiamo un metodo per
ciascuna delle funzioni del tipo astratto Realizziamo la funzione formaComplesso attraverso
un costruttore
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 45
. . . Rappresentazione del tipo Complesso
La specifica del tipo Complesso, con i suoi domini (tra cui quello di
interesse) e le sue funzioni, è quindi la seguente
Domini
Complesso : dominio di interesse del tipo
T1 : dominio dei valori che può assumere la parte reale di un numero complesso
T2 : dominio dei valori che può assumere la parte immaginaria di un numero complesso
T3 : dominio dei valori che può assumere il modulo di un numero complesso
T4 : dominio dei valori che può assumere la fase di un numero complesso
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 46
Funzioni (1 di 2) formaComplesso (T1 a, T2 b) Complesso
• pre: nessuna• post: RESULT è il valore corrispondente al numero
complesso a+ib
reale(Complesso c) T1 • pre: nessuna• post: RESULT è il valore corrispondente alla prima
componente del numero complesso
immaginaria(Complesso c) T2• pre: nessuna • post: RESULT è il valore corrispondente alla seconda
componente del numero complesso
. . . Rappresentazione del tipo Complesso
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 47
Funzioni (2 di 2) modulo(Complesso c) T3
• pre: nessuna • post: RESULT è il valore corrispondente al modulo del numero
complesso fase(Complesso c) T4
• pre: nessuna • post: RESULT è il valore corrispondente alla fase del numero
complesso add(Complesso c1, Complesso c2) Complesso
• pre: nessuna• post: RESULT è il valore che rappresenta il numero complesso
somma dei numeri complessi c1 e c2 molt(Complesso c1, Complesso c2) Complesso
• pre: nessuna • post: RESULT è il valore che rappresenta il numero complesso
prodotto dei numeri complessi c1 e c2
. . . Rappresentazione del tipo Complesso
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 48
public class Complesso extends Coppia {
// realizzazione delle funzioni del tipo astrattopublic Complesso(Double r, Double i) { super(r, i);}
public Double reale() { return ((Double) c1).doubleValue();}
public Double immaginaria() { return ((Double) c2).doubleValue();} . . .
. . . Rappresentazione del tipo Complesso
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 49
public Double modulo() { double re = ((Double) c1).doubleValue(); double im = ((Double) c2).doubleValue(); return new Double(Math.sqrt(re * re + im * im));}
public Double fase() { double re = ((Double) c1).doubleValue(); double im = ((Double) c2).doubleValue(); double ret; if (im >= 0) ret = Math.acos(re / modulo()); else ret = -Math.acos(re / modulo()); return new Double(ret);} . . .
. . . Rappresentazione del tipo Complesso
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 50
public Complesso add(Complesso cc) { double a = ((Double) c1).doubleValue(); double b = ((Double) c2).doubleValue(); double c = ((Double) cc.c1).doubleValue(); double d = ((Double) cc.c2).doubleValue(); return new Complesso(new Double(a+c),
new Double(b+d));}
public Complesso mult(Complesso cc) { double a = ((Double) c1).doubleValue(); double b = ((Double) c2).doubleValue(); double c = ((Double) cc.c1).doubleValue(); double d = ((Double) cc.c2).doubleValue(); return new Complesso(new Double(a*c - b*d),
new Double(b*c + a*d));}
}
. . . Rappresentazione del tipo Complesso
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 51
Esercizio
Implementare il tipo di dato astratto Complesso
basandosi sui valori di modulo e fase (insiemi
T3 e T4 del ADT) piuttosto che parte reale e
parte immaginaria (insiemi T1 e T2 del ADT)
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 52
Matrici sparse . . .
Ci sono dei casi in cui Ie caratteristiche dei
valori di una matrice, che si utilizzano in un
programma, consentono una memorizzazione
più efficiente rispetto a quella tradizionale con
array Ad esempio, per una matrice di interi in cui sia noto
che la grande maggioranza degli elementi è uguale a
zero, si potrebbero memorizzare i soli elementi
diversi da zero
Si usa il termine matrice sparsa . . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 53
. . . Matrici sparse
Si usa il termine matrice sparsa per indicare una matrice in cui la gran parte degli elementi ha un valore prefissato (detto valore dominante)
Per tali matrici si possono utilizzare rappresentazioni ad hoc, dette rappresentazioni compatte
L'idea fondamentale di tali rappresentazioni è quella di memorizzare solo gli elementi con valore diverso dal valore dominante
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 54
Esempio di matrice sparsa
00163003
00150002
00021001
00110080
543210
Elemento dominante = 0 Ogni elemento con valore diverso dal dominante viene rappresentato da una terna
Indice di riga Indice di colonna Valore dell’elemento
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 55
La rappresentazione compatta di una matrice sparsa...
Queste terne sono a loro volta rappresentate
mediante un array C di oggetti Terna con tre
attributi: riga, colonna e valore
Un indice lastValue rappresenta l’indice
dell’ultima terna significativa di C
C viene detta rappresentazione compatta di A
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 56
. . . La rappresentazione compatta di una matrice sparsa...
Gli oggetti Terna di C vengono memorizzati in modo ordinato, ad esempio ordinando per riga e, nell'ambito delIa stessa riga, per colonna La prima terna di C è utilizzata per memorizzare le
informazioni relative al numero di righe N ed il numero di colonne M di A, e nel campo relativo al valore, il valore dell' elemento dominante
Se max è il numero di componenti di C, e m (con m < max) è il numero di elementi di A memorizzati in C, Ie informazioni ad essi relative sono rappresentate negli elementi di indice da 1 a m di C, e nelle eventuali componenti successive di C (cioè quelIe di indice maggiore di m) viene memorizzata terna di valori che non corrisponde ad alcuna componente delIa matrice A
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 57
...La rappresentazione compatta di una matrice sparsa
Esempio: la rappresentazione compatta della seguente matrice
è
00163003
00150002
00021001
00110080
543210
rig col val
0 4 6 0
1 0 0 8
2 0 3 11
3 1 2 21
4 2 3 15
5 3 2 3
6 3 3 16
7 9 9 0
lastValue = 6
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 58
Quando conviene usare la rappresentazione compatta
Quando la matrice è sufficientemente sparsaSia A una matrice di m righe e n colonneSe maxA è il numero di elementi che si devono
memorizzare esplicitamente, l’occupazione di memoria richiesta per rappresentare
la matrice A in forma compatta è 3*(maxA+1) + 1 l’occupazione di memoria richiesta per rappresentare
la matrice A in forma usuale è m*n
La rappresentazione compatta risparmia memoria quando
3*(maxA+1) + 1< m*n … maxA < (m*n – 4)/3
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 59
La segnatura per il tipo matrice
interface MatriceDiInteri {boolean isEmpty();
//post: restituisce true sse la matrice e' vuota //r=c=0
int numRighe();//post: numero di righe della matrice
int numColonne();// post: numero di colonne della matrice
int accedi(int r, int c);//pre: r,c>=0//post: restituisce l'lemento in pos izione r,c
void memorizza(int r, int c, int n);//pre: r,c>=0//post: memorizza l'elemento n in posizione r,c
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 60
Due diverse implementazioni
Matrice con array: rappresentazione di JavaMatrice Compatta: rappresentazione efficiente
di una matrice sparsa
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 61
...Matrice con Array...
Attributi class MatriceConArray implements MatriceDiInteri {private int[][] mat;private int nrighe;private int ncolonne;
Il costruttore inizializza a 0 tutte le componentipublic MatriceConArray (int r, int c) {//costruttore int i,j; this.mat = new int[r][c]; //inizializza a zero for (i=0; i<r; i++) for(j=0; j<c; j++) this.mat[i][j] = 0; this.nrighe = r; this.ncolonne = c;}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 62
...Matrice con Array...
Metodi d’istanzapublic int numRighe(){// post: numero di righe della matrice return this.nrighe;}
public int numColonne(){// post: numero di colonne della matrice return this.ncolonne;}
public boolean isEmpty() {// post: restituisce true sse la matrice
// ha dimensioni nulle return (this.nrighe==0 && this.ncolonne==0);} . . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 63
...Matrice con Array
public int accedi(int r, int c){
//pre: r,c>=0
//post:restituisce l’elemento in posizione r,c
return this.mat[r][c];
}
public void memorizza(int r, int c, int n){
//pre: r,c>=0
//post:memorizza l'elemento n in posizione r,c
this.mat[r][c] = n;
} . . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 64
...Matrice con Array
public String toString(){ int i,j; String res = ""; for (i=0; i<nrighe; i++){ for(j=0; j<ncolonne; j++)
res = res + mat[i][j] +" "; res = res +"\n"; } return res;}
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 65
Matrice Compatta: la classe terna ...
Attributi class Terna {
int riga;int colonna;int valore;
Costruttorepublic Terna(int r, int c, int v){ riga = r; colonna = c; valore = v;}
Metodi d’istanzapublic int getRiga(){ return riga; }
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 66
...Matrice Compatta: la classe terna
public int getColonna(){
return colonna;
}
public int getValore(){
return valore;
}
public String toString(){
return (riga +" " + colonna +" " + valore);
}
}//end class Terna
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 67
Matrice Compatta...
class MatriceCompatta implements MatriceDiInteri {private Terna[] info;private int dim; // dimensione dell'arrayprivate int lastValue; // dimensione effettiva
// dell'array
Costruttore: inizializza tutte le terne a 0public MatriceCompatta (int dim, int rig,
int col, int dom) { int i; this.info = new Terna[dim]; this.info[0] = new Terna(rig,col,dom); for(i = 1; i < dim; i++) this.info[i] = new Terna(0,0,0); this.dim = dim; this.lastValue = 0;}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 68
...Matrice Compatta
public int numRighe() {// post: numero di righe della matrice return this.info[0].riga; }
public int numColonne() {// post: numero di colonne della matrice return this.info[0].colonna; }
public int getLastValue() {// post: dimensioni effettive della matrice return this.lastValue; }
public boolean isEmpty() {//post: restituisce true sse la matrice
// ha dimensioni nulle return (this.info[0].riga==0 &&
this.info[0].colonna==0); }
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 69
Matrice Compatta: il metodo accedi
public int accedi(int r, int c) {//pre: r,c>=0//post: restituisce l‘elemento in posizione r,c int i = 1, res; while (info[i].riga < r && i < this.lastValue) i++; //esco sulla riga r se esiste while (info[i].riga == r && info[i].colonna < c
&& i < this.lastValue)i++; //esco sulla colonna r se esiste
if (info[i].riga == r && info[i].colonna == c)res = info[i].valore;
elseres = info[0].valore;
return res;}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 70
Matrice Compatta: il metodo memorizza...public void memorizza(int r, int c, int n) {//pre: r,c>=0//post: memorizza l'elemento n in posizione r,c// se c'e' spazio
/* se si sostituisce un elemento diverso dal dominante con uno dominante, si devono shiftare tutti gli elementi in alto */ int i = 1, j; /* vedo se la componente da memorizzare esiste */ while (info[i].riga < r && i <= this.lastValue) i++; //esco sulla riga r se esiste while (info[i].riga == r && info[i].colonna < c
&& i <= this.lastValue) i++;
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 71
...Matrice Compatta: il metodo memorizza...
/* se il valore da memorizzare e' il dominante e se esiste gia' un valore nella matrice, allora devo eliminare la componente */ if (n == info[0].valore) { if (info[i].riga == r && info[i].colonna == c) {
//elimino l'el. in posizione i for (j = i+1; j < this.dim; j++)
info[j-1] = info[j]; this.lastValue = this.lastValue - 1;
}/* se il valore da memorizzare e' dominante
e se non esiste gia' un valore nella matrice, allora non devo fare niente */
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 72
...Matrice Compatta: il metodo memorizza...else { // n != info[0].valore/*il val. da memorizzare non e' dominante: se gia' esiste sovrascrivo altrimenti aggiungo */ if (info[i].riga == r && info[i].colonna == c) info[i].valore = n; // sovrascrivo else //aggiungo se c'e' posto if (this.lastValue == this.dim-1) System.out.println
("** Memorizzazione impossibile **"); else { for(j = this.lastValue; j >= i; j--)
this.info[j+1] = this.info[j]; this.lastValue = this.lastValue + 1; info[i] = new Terna(r,c,n); }
}}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 73
...Matrice Compatta: il metodo toString
public String toString() {
int i;
String res;
res = "";
for (i=0; i<=lastValue; i++)
res = res +(info[i].toString()) + "\n";
return res;
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 74
Matrice Compatta: esempi d’uso...
La classe UsaMatrici usa una MatriceConArrayclass UsaMatrici{
public static void main(String[] args){MatriceConArray emme;
emme = new MatriceConArray(4,6);System.out.println(emme.toString());emme.memorizza(1,2,9);emme.memorizza(3,4,7);emme.memorizza(2,2,8);System.out.println(emme.toString());}
}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 75
Matrice Compatta: esempi d’uso...
Esempio di esecuzione con MatriceConArray
0 0 0 0 0 00 0 0 0 0 00 0 0 0 0 00 0 0 0 0 0
0 0 0 0 0 00 0 9 0 0 00 0 8 0 0 00 0 0 0 7 0
Press any key to continue . . .
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 76
...Matrice Compatta: esempi d’uso...
La classe UsaMatrici usa una MatriceCompattaclass UsaMatrici{
public static void main(String[] args){
MatriceCompatta emme;
emme = new MatriceCompatta(5,4,6,0);
emme.memorizza(1,2,9);
emme.memorizza(3,4,7);
emme.memorizza(2,2,8);
System.out.println(emme.toString());
}}
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 77
Matrice Compatta: esempi d’uso...
Esempio di esecuzione con MatriceCompatta4 6 0
inserisco in riga 1, colonna 2 il valore 94 6 01 2 9
inserisco in riga 3, colonna 4 il valore 74 6 01 2 93 4 7
inserisco in riga 2, colonna 2 il valore 84 6 01 2 92 2 83 4 7
http://www.dia.uniroma3.it/~java/fondinf/ Esercizi 78
Esercizio
Definire, secondo la segnatura MatriceDiInteri una classe concreta che rappresenta una matrice compatta usando una sequenza di terne (struttura collegata) invece di un array di terne