[Seq]
Consideriamo sequenze di valori rappresentate dalla seguente
interfaccia generica:
public interface Seq<V> {
//Ritorna l'i-esimo valore della sequenza,
V get(int i); //la numerazione inizia da 0
int length(); //Ritorna la lunghezza della sequenza
}
Ad esempio, una classe che rappresenta sequenze di interi potrebbe chiamarsi
IntSeq
e
implementare
Seq<Integer>
.
Vogliamo definire una classe che gestisce un insieme di sequenze ordinato
lessicograficamente. In questo ordinamento, (
v0,...,
vn)
< (
u0,...,
um) se o
n <
m
e
v0 =
u0,...,
vn =
un
o esiste
i ≤
n,
m tale che
v0 =
u0,...,
vi − 1 =
ui − 1
e
vi <
ui. Due sequenze sono uguali se hanno la stessa lunghezza
e in ogni posizione hanno valori uguali (secondo il metodo
equals
del tipo
V
). Si tenga presente che
il metodo
equals
di un oggetto di tipo
Seq<V>
non implementa questa
relazione di uguaglianza.
- (max 16 punti)
Definire una classe
SeqSet
con parametro di tipo V
per gestire un insieme di
sequenze (di tipo Seq<V>
) ordinato lessicograficamente. Per determinare l'ordinamento
la definizione deve richiedere che il tipo V
implementi l'interfaccia Comparable
relativamente al tipo V
o a un suo supertipo. La classe deve realizzare le seguenti
funzionalità.
- Due costruttori, uno senza argomenti che costruisce l'insieme vuoto e uno che prende una
Collection
, con parametro di tipo il più generale possibile, e
costruisce l'insieme con gli elementi (distinti) della collezione.
- Metodi
add
, contains
e remove
che ritornano un booleano, prendono in input
una sequenza e si comportano come gli omonimi metodi di Set
.
- Un metodo
ceiling
che prende in input una sequenza s
e ritorna la sequenza
nell'insieme che nell'ordinamento lessicografico è la minima tra quelle maggiori od uguali a s
.
Se una tale sequenza non c'è, ritorna null
.
- Implementa l'interfaccia
Iterable
per iterare sulle sequenze dell'insieme
in ordine lessicografico ascendente.
Tutti i metodi e costruttori lanciano NullPointerException
se il parametro di input è null
.
- (max 16 punti)
Definire una sottoclasse
SubSeqSet
di SeqSet
che gestisce insiemi di sequenze
che sono sottosequenze di una sequenza base, fornita al momento della costruzione. Si ricorda che s1 è una
sottosequenza di s2 se s1 si può ottenere eliminando da
s2 zero o più elementi. Ad es. (2,2,1) e (1,3,4,2) sono sottosequenze di (1,2,3,4,3,2,1),
ma (2,2,3) non lo è. La classe SubSeqSet
deve realizzare le seguenti funzionalità.
- Due costruttori, uno prende in input solo la sequenza di base e costruisce l'insieme vuoto,
l'altro oltre alla sequenza di base prende una
Collection
(come il costruttore di SeqSet
)
e costruisce l'insieme con le sequenze (distinte) della collezione che sono sottosequenze della
sequenza di base.
- Ridefinisce il metodo
add
per impedire che si possano aggiungere sequenze che
non siano sottosequenze della sequenza di base.
- Un metodo
count
che ritorna una mappa (di tipo Map
), con chiavi di tipo V
,
che ad ogni valore presente nella sequenza di base associa il numero di sequenze dell'insieme che contengono
tale valore.
[Errori] (
max 8 punti)
Il seguente codice Java contiene uno o più errori. Trovare gli errori, spiegarli e
dire per ognuno se si verifica in compilazione o in esecuzione.
1 import java.util.*;
2
3 public class Test {
4 public static <E> E[] copyifnull(List<? extends E> list, E[] a) {
5 int i = 0;
6 for (E x : list)
7 if (a[i] == null)
8 a[i++] = x;
9 return a;
10 }
11 public static void main(String[] args) {
12 List<Integer> iL = new ArrayList<Integer>();
13 iL.add(5);
14 List<? extends Integer> eL = iL;
15 Object[] objA = new Object[10];
16 copyifnull(eL, objA);
17 int val = eL.get(0);
18 objA = new String[50];
19 copyifnull(eL, objA);
20 eL.add(new Integer(7));
21 List<?> list = iL;
22 Object o = list.get(0);
23 val = (int)o;
24 val = list.get(0);
25 objA = copyifnull(list, new Object[10]);
26 }
27 }