Metodologie di Programmazione a.a. 2010-2011 (canale M-Z)
Esercizi di preparazione alla prova intermedia
Si vuole definire una classe che permette di calcolare informazioni statistiche circa
sorgenti Java contenuti in file.
-
Definire una classe
JavaCode che gestisce un file che contiene codice Java. Il costruttore
prende come parametro il pathname di un file e lo apre in lettura. Definire un metodo countClasses
che ritorna il numero di occorrenze della parola chiave class nel file.
-
Definire un metodo
maxDepth della classe JavaCode che ritorna la massima
profondità di nidificazione di blocchi {...}, secondo i seguenti esempi:
maxDepth ritorna 3 maxDepth ritorna 4
public class A { class B { B() {} }
public A() {} public class Test {
private int calc() { public static void main(String[] args) {
while (true) { for (int i = 0 ; i < 5 ; i++) {
break; while (true) { int k = get(); }
} }
} }
} private int get() { return 1; }
}
-
Usare la classe
JavaCode per scrivere un programma che legge dalla linea di comando il
pathname di un file (si assume contenga codice Java) e stampa il numero di definizioni di classi
presenti nel file e la massima profondità di nidificazione.
Definire delle classi per la gestione (semplificata) di operazioni bancarie,
rispettando le seguenti indicazioni.
-
Definire una gerarchia di classi per la gestione di semplici
operazioni bancarie: prelievo, versamento e bonifico. Definire una classe base
Operazione per gestire i dati comuni a tutte le operazioni bancarie: la data
dell'operazione (una stringa), il numero di conto corrente (un intero positivo) e l'importo dell'operazione
(un float positivo). Definire poi le sottoclassi Prelievo, Versamento
e Bonifico. La classe Prelievo deve gestire il dato che indica da dove è
stato effettuato il prelievo (una stringa, ad esempio "bancomat").
La classe Versamento deve gestire il dato che indica il mezzo usato per il versamento
(una stringa, ad esempio "contanti") e un dato opzionale che
riporta la causale del versamento (una stringa) che essendo opzionale non deve essere
inizializzata nel costruttore ma dovrà esserci un metodo setCausale per
fare ciò. La classe Bonifico deve gestire il dato che indica il beneficiario
del bonifico (una stringa, ad esempio le coordinate bancarie del beneficiario) e un dato opzionale
per la causale del bonifico che deve essere trattato come la causale della classe
Versamento. Definire un metodo getCC che ritorna il numero di conto corrente,
un metodo getImporto che ritorna l'importo e un metodo stampa che stampa la
descrizione dell'operazione. Rendere gli oggetti di tutte le classi immutabili eccetto che per la
causale.
-
Definire una classe
Conto per gestire i dati dei
conti correnti: il numero del conto (un intero positivo), l'intestatario (una stringa), il
saldo (un float positivo, negativo o zero) e la lista di tutte le operazioni
effettuate sul conto corrente (un array di Operazione). Il costruttore prende
come parametri il numero di conto e l'intestatario. Il saldo è inizializzato a zero.
Definire un metodo aggiorna che prende in input un oggetto Operazione
e se rappresenta una operazione relativa al conto corrente aggiunge l'operazione alla lista
e aggiorna il saldo. Definire un metodo movimenti che prende in input un intero
n e stampa le descrizioni delle ultime n operazioni e il saldo.
Il seguente codice Java contiene uno o più errori. Trovare gli errori
e spiegarli. In particolare, dire per ogni errore se si verifica in compilazione o
durante l'esecuzione.
public class Test {
public static void main(String[] args) {
if (args instanceof String) return;
float[][] matrix = new float[5][];
Object[] oA = matrix;
if (oA instanceof float[]) return;
oA = new int[10];
Object[] oB = new int[5][4];
oA = matrix;
oA[0] = oB[0];
}
}
Definire una classe
Table che permette di tradurre i dati contenuti in un file
in forma tabellare.
-
La classe
Table ha un costruttore che prende in input il pathname di un file.
Si assume che il file sia un file di tipo testo con il seguente formato: ogni linea contiene
k stringhe separate dal carattere ';' (k è lo stesso per tutte
le linee però può cambiare da file a file). Tale k è il numero di colonne
del file e quindi anche della tabella. La classe ha un metodo int[] colWidths() che ritorna un array w
di lunghezza pari al numero di colonne del file e tale che w[i] è la massima
lunghezza delle stringhe della colonna i.
-
La classe ha un metodo
print
che stampa a video il contenuto del file in forma tabellare come nel seguente esempio:
File: temperature.txt Risultato di print()
Città;MIN;MAX FILE: temperature.txt
Roma;2;18 Città | MIN | MAX |
L'Aquila;-12.5;9 -------------------------------
Reggio Calabria;5;21 Roma | 2 | 18 |
L'Aquila | -12.5 | 9 |
Reggio Calabria | 5 | 21 |
La prima colonna è giustificata a sinistra e le altre sono giustificate a destra.
-
Scrivere un programma che usa la classe
Table e legge dallo standard input
il pathname di un file e stampa a video il contenuto del file in forma di tabella.
Si vuole gestire l'archivio dei documenti (libri e DVD) di una biblioteca. Ogni documento
ha una collocazione. Prima di tutto definire quindi una classe
Collocazione
per gestire le collocazioni e i cui oggetti devono essere immutabili. Una collocazione
è determinata da una stringa
che specifica il nome di un reparto della biblioteca, un numero di scaffale che identifica
uno scaffale del reparto e da un numero che indica una posizione nello scaffale.
Poi, definire una gerarchia di classi secondo le seguenti indicazioni.
-
Definire una classe base
Documento e poi le sottoclassi Libro,
DVD_Video e DVD_Audio. Un oggetto di tipo Libro
consiste in una collocazione (un oggetto di tipo Collocazione), una stringa
contenente l'autore o gli autori del libro, una stringa contenente il titolo e un intero
contenente il numero di pagine. Un oggetto
DVD_Video consiste in una collocazione, una stringa che contiene il titolo
del film, una stringa che contiene il regista o i registi e un intero che contiene la
durata in minuti del film. Un oggetto DVD_Audio consiste in una collocazione,
una stringa che contiene il nome della casa discografica, una stringa che contiene il titolo
del DVD e per ogni brano una stringa contenente il titolo del brano.
I costruttori devono inizializzare tutti i campi.
Definire un metodo getColl
che ritorna la collocazione del documento.
Definire un metodo stampa che stampa tutte le informazioni relative al documento.
Definire un metodo cercaInTitolo che prende in input una stringa str
e ritorna true o false a seconda che str sia contenuta
o meno nel titolo del documento.
-
Definire un metodo statico
cercaTitoli della classe Documento
che prende in input un array arrD di oggetti Documento e
una stringa str e ritorna in un nuovo array
tutti i documenti dell'array arrD il cui titolo contiene la stringa str.
Il seguente codice Java contiene uno o più errori. Trovare gli errori
e spiegarli. In particolare, dire per ogni errore se si verifica in compilazione o
durante l'esecuzione.
class Pair {
private String key, value;
public Pair(String k, String v) {
key = k;
value = v;
}
public String getKey() { return key; }
}
class CountPair extends Pair{
private int count;
public CountPair(String k, String v, int c) {
super(k, v);
count = c;
}
public int getCount() { return count; }
}
public class Test {
public static void main(String[] args) {
Pair[] pp = new Pair[3];
pp[0] = new CountPair("K", "V", 1);
pp[1] = new Pair("KK", "VV");
System.out.println(pp.getKey()+pp.getCount());
int count = ((CountPair)pp[1]).getCount();
String s = pp[2].getKey();
}
}
Due stringhe
s1 e
s2 sono
anagrammi l'una dell'altra se
ogni carattere di
s1 o di
s2 occorre lo stesso numero di volte
in
s1 e in
s2.
-
Definire una classe
Anagrammi per rappresentare insiemi di anagrammi. Il costruttore
prende in input una stringa e costruisce l'insieme composto da tale stringa. Definire un metodo
aggiungi che prende in input una stringa s e se s è
un anagramma delle stringhe nell'insieme ed è diversa da tutte le stringhe dell'insieme
allora la aggiunge all'insieme e ritorna true, altrimenti non fa nulla e ritorna
false.
-
Definire un metodo
seleziona della classe Anagrammi che prende
in input un array di stringhe sA e elimina dall'insieme tutte le stringhe
che non appaiono nell'array sA.
Definire una piccola gerarchia di classi per rappresentare quiz di vario genere
(a scelta multipla, a risposta numerica e a risposta testuale)
rispettando le seguenti indicazioni.
-
Definire una classe base
Quiz e le sottoclassi QuizMulti,
QuizNumber e QuizWord. La classe Quiz gestisce
i dati comuni: il testo del quiz (una stringa) e il punteggio (un intero).
La sottoclasse QuizMulti rappresenta quiz a scelta multipla e deve quindi
gestire un array di stringhe rappresentanti le possibili scelte e la risposta
corretta, un char con il seguente significato: 'A'
indica la prima scelta, 'B' indica la seconda scelta, e così via.
La sottoclasse QuizNumber rappresenta quiz con risposta numerica e deve gestire
un array di possibili risposte corrette (un array di int). La sottoclasse
QuizWord rappresenta quiz con risposta data da una parola e deve gestire
un array di possibili risposte corrette (un array di stringhe). Definire un metodo
getScore che ritorna il punteggio del quiz. Definire un metodo isCorrect
che prende in input una stringa answer e ritorna true o
false a seconda che answer sia una risposta corretta o meno.
Nel caso della classe Quiz il metodo ritorna sempre false,
le sottoclassi devono ridefinire il metodo. Per QuizMulti solo il primo carattere
di answer va considerato. Per QuizNumber la stringa answer
va interpretata come un intero (si può usare il metodo Integer.parseInt()) e la
risposta è corretta solo se l'intero è presente nell'array delle risposte corrette.
Per QuizWord la risposta è corretta solo se answer è
uguale a una delle stringhe dell'array delle risposte corrette. Definire inoltre un metodo
print che prende in input un intero n è stampa il quiz come
nel seguente esempio (in questo caso n = 3, il quiz è a scelta multipla,
il testo è "Come si chiama il satellite del pianeta Terra?", il punteggio è 5
e le possibili scelte sono "Giove", "Luna", "Marte",
"Urano"):
Quiz 3 (score 5)
Come si chiama il satellite del pianeta Terra?
A. Giove
B. Luna
C. Marte
D. Urano
-
Definire una classe
QuizTest con un metodo statico readQuizFile che
prende in input il pathname di un file contenente una batteria di quiz e ritorna in un array
di oggetti Quiz i quiz letti dal file. Ogni linea del file definisce un quiz secondo
il seguente formato: X#T#S#R1#R2#...#RK. X è un carattere che
indica il tipo del quiz: 'M' scelta multipla, 'N' a risposta numerica
e 'W' a risposta testuale. T è una stringa che definisce il testo
del quiz e S è una stringa che rappresenta il punteggio. Il significato delle
altre stringhe R1,..., Rk dipende dal tipo di quiz. Se X =
'M' allora R1 è un singolo carattere che rappresenta la risposta
corretta e R2,..., Rk sono le scelte multiple. Se X =
'N' allora R1,..., Rk sono stringhe che rappresentano
le risposte numeriche corrette. Se X = 'W' allora R1,...,
Rk sono le risposte corrette.
-
Definire per la classe
QuizTest un metodo main che, usando il
metodo readQuizFile, legge dalla linea di comando i pathname di due file:
il primo contiene una batteria di quiz secondo il formato
specificato al punto (b) e il secondo contiene delle risposte per tali quiz con una
risposta (stringa) per linea. Poi il metodo main
deve stampare per ogni quiz, il testo del quiz, la relativa risposta, l'indicazione
se la risposta è corretta o meno.
Infine deve stampare il punteggio totale (somma dei punteggi ottenuti in tutti i quiz).
Ad esempio se i due file contengono:
FILE DEI QUIZ: FILE DELLE RISPOSTE:
M#Come si chiama il satellite della Terra?#4#B#Giove#Luna#Marte C
W#Una provincia dell'Umbria.#3#Terni#Perugia Terni
N#Un numero primo tra 30 e 40.#2#31#37 31
Allora il main stampa:
Quiz 1 (score 4)
Come si chiama il satellite della Terra?
A. Giove
B. Luna
C. Marte
Answer: C NOT CORRECT
Quiz 2 (score 3)
Una provincia dell'Umbria.
Answer: Terni CORRECT
Quiz 3 (score 2)
Un numero primo tra 30 e 40.
Answer: 31 CORRECT
Total score: 5
Il seguente codice Java contiene uno o più errori. Trovare gli errori
e spiegarli. In particolare, dire per ogni errore se si verifica in compilazione o
durante l'esecuzione.
class Value {
private Object value;
public Value(Object v) { value = v; }
public void setValue(String v) { value = v; }
public Object getValue() { return value; }
}
class ValueString extends Value {
public ValueString(String s) { super(s); }
}
public class Test {
public static void main(String[] args) {
Value[] val = new Value[2];
val[0] = new Value(new Value("A"));
val[1] = new ValueString("B");
Value v = val[0].getValue();
Object obj = val[0].getValue();
String s = (String)obj;
String ss = (String)val[1].getValue();
}
}
Definire una classe
IntRect per gestire rettangoli con lati paralleli
agli assi e con coordinate intere. Ogni rettangolo è quindi determinato
da quattro coordinate di tipo
int x1,
x2,
y1 e
y2 tali che
(x1, y1),
(x1, y2),
(x2, y1) e
(x2, y2) sono le coordinate dei quattro spigoli
del rettangolo. Assumeremo che valga sempre
x1 <= x2 e
y1 <= y2.
Un punto di coordinate
(x, y) appartiene
ad un rettangolo di coordinate
(x1, x2, y1, y2) se
x1 <= x <= x2
e
y1 <= y <= y2.
-
Definire, usando la classe
IntRect, una classe DisjointRectSet
per gestire insiemi di rettangoli (del tipo rappresentato da IntRect)
a due a due disgiunti. Si osservi che due rettangoli sono disgiunti se nessuno spigolo del
primo rettangolo appartiene al secondo e nessuno spigolo del secondo rettangolo appartiene
al primo. Il costruttore della classe inizializza l'insieme
come vuoto. Inoltre la classe deve avere due metodi add e isDisjoint.
Il metodo add permette di aggiungere un rettangolo (tramite un argomento di tipo
IntRect) all'insieme se è disgiunto da tutti i rettangoli dell'insieme e
ritorna true, altrimenti non fa nulla e ritorna false. Il metodo
isDisjoint prende come argomento un rettangolo di tipo IntRect
e ritorna true o false a seconda che il rettangolo sia o meno
disgiunto da tutti i rettangoli nell'insieme.
-
Aggiungere alla classe
DisjointRectSet un metodo statico
create che prende in input un array di IntRect e se i rettangoli
dell'array sono a due a due disgiunti ritorna un oggetto di tipo DisjointRectSet
che rappresenta l'insieme dei rettagoli dell'array, altrimenti ritorna null.
-
Definire un'altro costruttore della classe
DisjointRectSet che prende in input
il pathname di un file che su ogni linea contiene quattro interi separati da spazi
da interpretarsi come coordinate (x1, x2, y1, y2) di un rettangolo. Se tutti i
rettangoli sono disgiunti allora l'oggetto costruito rappresenta tale insieme di rettangoli,
altrimenti rappresenta l'insieme vuoto.
Una fabbrica deve mantenere un archivio
degli ingranaggi che produce. Gli ingranaggi si suddividono in semplici
(ad es. ruote dentate, pignoni, ecc.) e composti. Definire
una gerarchia di classi, secondo le indicazioni seguenti, per gestire
detto archivio.
-
Definire una classe base
Ingranaggio per gestire i dati comuni:
il codice (una stringa) e la dimensione (altezza, larghezza e profondità in mm)
rappresentata tramite una classe nidificata statica e immutabile. Entrambi i campi devono
essere immutabili. Definire metodi per leggerli. La classe deve ridefinire
il metodo equals() di Object.
Due ingranaggi sono uguali se hanno lo stesso codice.
• Definire una sottoclasse IngrSemplice per
gestire i dati di un ingranaggio semplice: il tipo (una stringa) immutabile e
l'insieme degli ingranaggi compatibili con questo ingranaggio
(cioè, che possono funzionare assieme).
Definire un metodo per leggere il tipo. Definire un metodo isCompatibile()
che prende come parametro un ingranaggio ingr e ritorna true se
ingr è compatibile con questo ingranaggio. Definire un metodo
add() che preso come parametro un ingranaggio ingr lo aggiunge
all'insieme degli ingranaggi compatibili solo se non è già presente
e non è null.
• Definire una sottoclasse IngrComposto per
gestire i dati di un ingranaggio composto: l'elenco degli ingranaggi componenti (diretti)
(questi possono essere sia semplici che composti). Definire un metodo componentCount()
che preso come parametro un ingranaggio ingr ritorna il numero di ingranaggi
uguali a ingr che sono componenti (diretti o indiretti) di questo ingranaggio.
Ad esempio, se l'elenco di un ingranaggio di codice "C0"
consiste di ingranaggi con i codici ["S1", "S2", "S1", "C1",
"C1"]
e "C1" è un ingranaggio composto il cui elenco è
["C2", "S2"] e "C2" è un ingranaggio composto il
cui elenco è ["S1", "S2"], allora il metodo componentCount()
invocato sull'ingranaggio "C0" con input un ingranaggio di codice "S2"
ritorna 5, se l'input ha codice
"C2" ritorna 2 e se l'input ha codice "S1" ritorna 4.
Definire un metodo add() che preso come parametro un ingranaggio ingr
lo aggiunge all'elenco degli ingranaggi componenti solo se ingr non è
null e non contiene (direttamente o indirettamente) questo ingranaggio come
componente. Rispetto all'esempio precedente, il metodo add() invocato sull'ingranaggio
con codice "C2" non deve permettere l'aggiunta dell'ingranaggio
con codice "C0".
• Tutte e quattro le classi
devono ridefinire il metodo toString() di
Object ritornando una stringa che riporta tutti i dati dell'oggetto.
-
Aggiungere alla classe
IngrComposto
un metodo getCompSemplici() che ritorna in un array tutti gli ingranaggi
semplici che sono componenti diretti o indiretti di questo ingranaggio. Rispetto all'esempio
precedente, se il metodo è invocato sull'ingranaggio di codice "C0"
ritorna un array che contiene ingranaggi con i seguenti codici ["S1",
"S2", "S1", "S1", "S2", "S2",
"S1", "S2", "S2"].
Il seguente codice Java contiene uno o più errori. Trovare gli errori
e spiegarli. In particolare, dire per ogni errore se si verifica in compilazione o
durante l'esecuzione.
public class Test {
public static class SubTest extends Test {
public SubTest(int c) { super(c); }
}
public final int count;
public Test(int c) { count = c; }
public SubTest[][] matrix() {
Object[] a = new SubTest[count][];
for (int i = 0 ; i < a.length ; i++)
a[i] = new SubTest[i];
return (SubTest[][])a;
}
public static void main(String[] args) {
Object[][] oA = new SubTest(10).matrix();
int c = ((Test)(oA[5][0])).count;
oA[3][0] = new SubTest(5);
}
}
Due numeri interi positivi
n e
m si dicono
coprimi se non hanno
divisori in comune oltre a 1. Ad esempio, 8 e 9 sono coprimi ma 9 e 12 non sono coprimi.
-
Definire una classe
Coprimi per gestire insiemi di numeri interi tra loro
coprimi. Il costruttore inizializza l'insieme come vuoto. La classe ha due metodi
aggiungi e mcd. Il metodo aggiungi prende come argomento
un intero e se questo è coprimo con tutti i numeri nell'insieme lo aggiunge all'insieme
e ritorna true, altrmenti non fa nulla e ritorna false. Il metodo
mcd prende come argomento un intero e ritorna il massimo comun divisore
tra l'intero e gli interi dell'insieme. Ad esempio se l'insieme è {15, 14, 11}
e l'argomento è 35 allora il metodo ritorna 7.
-
Aggiungere alla classe
Coprimi un metodo intersezione che
prende come argomento un oggetto di tipo Coprimi e ritorna un nuovo oggetto
di tipo Coprimi che contiene l'intersezione dei due insiemi.
-
Definire un'altro costruttore della classe
Coprimi che prende in input
il pathname di un file che su ogni linea contiene un intero. Se tutti gli interi
sono coprimi allora l'oggetto costruito rappresenta tale insieme di interi, altrimenti
rappresenta l'insieme vuoto.
Si vuole definire una piccola gerarchia di classi per rappresentare trasformazioni
di stringhe che potrebbero risultare utili in una varietà di contesti
(analisi di testi, compressione dati, ecc.).
-
Definire una classe base
Transform che gestisce l'unico dato comune
a tutte le trasformazioni: la descrizione (una stringa) che deve essere immutabile.
Definire un metodo per leggere la descrizione o rendere il campo pubblicamente accessibile.
Gli oggetti di tipo Transform devono essere istanziabili solamente
da classi nello stesso package o da sottoclassi di Transform. Definire
un metodo String apply(String s) che ritorna la stringa di input s
e che sarà opportunamente ridefinito dalle sottoclassi.
• Definire una sottoclasse Cycle per rappresentare
permutazioni cicliche. Una premutazione ciclica è determinata da un array di interi
C = [i0,i1,...,in-1].
Il metodo apply(s) trasforma s (di lunghezza L)
così che il carattere in posizione i0%L va in posizione
i1%L,
quello che era in posizione i1%L va in i2%L
... e infine il carattere che era in posizione in-1%L va in
i0%L. Ad esempio, se C=[1,6,0]
e s="abcd" allora il metodo apply(s) ritorna "cabd".
Gli oggetti di tipo Cycle devono essere immutabili. Il costruttore
deve lanciare IllegalArgumentException se l'array C è null o
ha lunghezza minore 2 o contiene valori minori di zero. La classe deve ridefinire il metodo
equals() di Object: due oggetti di tipo Cycle sono uguali
se i relativi array hanno la stessa lunghezza e sono uguali a meno di rotazioni. Ad esempio,
gli array [0,3,4] e [3,4,0] sono equivalenti.
• Definire una sottoclasse Replace per
rappresentare sostituzioni periodiche. Una sostituzione periodica è determinata
da una fase f, un periodo p e due array
di caratteri I e O. Il metodo apply(s)
trasforma s (di lunghezza di L) nel seguente modo:
per ogni i=0,1,2... tale che
j = f+i*p < L, se il carattere
in posizione j di s è in una qualche posizione
k di I allora il carattere in posizione
j è sostituito con O[k].
Ad esempio, se f=1, p=2, I=['a','b','c'],
O=['A','B','C'] e s="aabbcdaa" allora apply(s)
ritorna "aAbBcdaA". Gli oggetti di tipo Replace devono essere immutabili.
Il costruttore deve lanciare IllegalArgumentException se f<0
o p<1 o I=null o O=null
o gli array I e O hanno lunghezze differenti o
I contiene caratteri ripetuti. La fase e il periodo devono essere
pubblicamente accessibili. La classe deve ridefinire il metodo equals() di
Object: due oggetti x e x'
di tipo Replace sono uguali se hanno la fase,
lo stesso periodo e i relativi array I, O e
I', O' sono tali che I
e I' hanno la stessa lunghezza, contengono gli stessi caratteri
e le sostituzioni sono le stesse. Ad esempio, I=['a','b','c'], O=['A','B','C']
e I'=['b','a','c'], O'=['B','A','C']
sono equivalenti.
• Definire una sottoclasse Compound per rappresentare
trasformazioni composte. Una trasformazione composta è determinata da due trasformazioni
t1 e t2.
Il metodo apply(s) applica ad s prima la trasformazione
t1 e poi la trasformazione t2.
Gli oggetti di tipo Compound devono essere immutabili.
Il costruttore deve lanciare IllegalArgumentException se o t1
o t2 è null. La classe deve ridefinire
il metodo equals() di Object: due oggetti di tipo Compound
sono uguali se le rispettive trasformazioni componenti sono uguali.
-
Aggiungere alla classe
Compound
un metodo int replaceCount(int f, int p) che ritorna il numero di trasformazioni
di tipo Replace con fase f e periodo p contenute,
direttamente o indirettamente, nella trasformazione composta. Ad esempio, se
il metodo replaceCount(0, 1) è invocato su una trasformazione
composta dalle trasformazioni R, C
e R è di tipo Replace con fase 0 e periodo 1,
C è composta da R', Y
e R' è di tipo Replace con fase 0 e periodo 1 e
Y è di tipo Cycle, allora il metodo ritorna 2.
Il seguente codice Java contiene uno o più errori. Trovare gli errori
e spiegarli. In particolare, dire per ogni errore se si verifica in compilazione o
durante l'esecuzione.
public class Test {
public static void main(String[] args) {
long[] arrL = new long[10];
String[] arrStr = new String[20];
arrL[0] += 5;
arrL[1] = arrStr[0].length();
Object[] arrObj = new Object[20];
arrObj[0] = arrL;
arrObj[1] = arrStr;
arrObj[2] = ((String[])arrObj[0])[0];
Object[][] mObj = new Object[10][];
mObj[0] = arrL;
mObj[1] = arrStr;
}
}
Definire una classe
Mappa per gestire mappe altimetriche.
Una mappa altimetrica è rappresentata tramite
una matrice
rettangolare di interi
M tale che
M[i][j] è
l'altezza (in metri rispetto al livello del mare) del punto
(i, j).
-
Definire un costruttore che prende come argomenti due interi
nr
e nc e costruisce una mappa nr×nc i cui elementi
sono inizializzati a zero. Definire inoltre i seguenti metodi. Un metodo set
che prende come argomenti tre interi i, j e h e imposta
l'altezza del punto (i, j) ad h. Un metodo max che
ritorna la massima altezza della mappa. Un metodo stampa che stampa la mappa
come nel seguente esempio (è una mappa 3×4):
0 2 3 2
0 1 2 1
-1 0 1 0
-
Definire un'altro costruttore che prende come argomento una mappa (di tipo
Mappa)
e costruisce una copia di tale mappa.
-
Definire un ulteriore costruttore che prende in input il pathname di un file. Il file
ha il formato seguente. La prima linea contiene due interi
nr e nc,
separati da spazi, che specificano la dimensione della matrice. Le nr
linee successive contengono ognuna nc interi separati da spazi.
Si vuole definire una piccola gerarchia di classi per rappresentare entità geografiche
come fiumi, laghi e città.
-
Definire una classe base
Geo che gestisce i dati comuni: il codice (una stringa) e il nome
(una stringa) dell'entità geografica. Definire metodi che ritornano il codice e il nome e un metodo
che stampa tutti i dati relativa all'entità (che sarà ridefinito dalle sottoclassi).
Definire una sottoclasse Fiume che gestisce il dato lunghezza del fiume in Km. Definire una
sottoclasse Città che gestisce il numero di abitanti e il riferimento ad
un oggetto Fiume che rappresenta l'eventuale fiume che attraversa la città (se la città
non è attraversata da un fiume, il riferimento sarà null). Definire metodi
che permettono di impostare il fiume e di leggerlo. Definire una sottoclasse Lago che gestisce
l'elenco dei fiumi immissari e l'elenco dei fiumi emissari del lago (entrambi elenchi di oggetti di tipo
Fiume). Definire un metodo che permette di
aggiungere un fiume immissario all'elenco degli immissari solamente se non è già presente e ritorna
true, altrimenti ritorna false. Definire un metodo analogo per aggiungere un
emissario. Due entità geografiche sono considerate uguali se hanno lo stesso codice.
-
Aggiungere alla classe
Geo un metodo statico che preso in input un array G
di Geo e un oggetto Fiume, ritorna in un array di Città
tutte le città contenute nell'array G che sono attraversate dal fiume di input.
Si ricorda che due entità geografiche sono considerate uguali se hanno lo stesso codice.
Definire una classe
Punto per rappresentare punti del piano a coordinate
intere. Definire una gerarchia di classi per gestire figure geometriche del piano (cerchi,
rettangoli e triangoli) a coordinate intere secondo le indicazioni seguenti.
-
Definire una classe base
Figura2D e le sottoclassi Cerchio,
Rettangolo e Triangolo. Ogni oggetto di tipo Cerchio
è determinato da un centro di tipo Punto e un raggio (intero). Ogni
oggetto Rettangolo è determinato da due punti (di tipo
Punto) rappresentanti lo spigolo in alto a sinistra e quello in basso
a destra (il rettangolo ha i lati paralleli agli assi). Ogni oggetto Triangolo
è determinato da tre punti (i vertici del triangolo). Definire un metodo area
che ritorna l'area della figura geometrica. Definire un metodo minR
che ritorna un oggetto Rettangolo che è il più piccolo
rettangolo che contiene la figura geometrica. Definire inoltre un metodo isIn
che prende in input un punto
(di tipo Punto) e ritorna true o false a seconda che il
punto cada all'interno o all'esterno della figura geometrica.
-
Definire un metodo statico
maxArea della classe Figura2D
che prende in input un array di
Figura2D e ritorna la massima area delle figure geometriche dell'array.
-
Definire un metodo statico
minRettangolo della classe Figura2D
che prende in input un array di Figura2D e ritorna un oggetto
Rettangolo che è
il più piccolo rettangolo che contiene tutte le figure geometriche dell'array.
Il seguente codice Java contiene uno o più errori. Trovare gli errori
e spiegarli. In particolare, dire per ogni errore se si verifica in compilazione o
durante l'esecuzione.
public class Esame {
public static void main(String[] args) {
int[][] mat = new int[8][];
for (int i = 0 ; i < mat.length ; i++)
mat[i][0] = i;
Object[] objA = mat;
if (objA instanceof int[]) return;
Object[][] objM;
objM = mat;
Object[] oF = new float[5][5];
((float[])oF[1])[2] = 2.8f;
objM = (Object[][])oF;
}
}