Examen final - solution
1 Flots compressés
Partie 1
Le patron Decorator, qui nous permet de décorer un flot d'entrée quelconque pour lui ajouter la possibilité de décompresser un flot compressé.
Partie 2
public final class RLEInputStream extends InputStream {
private InputStream stream;
private int value = -1;
private int count = 0;
public RLEInputStream(InputStream stream) {
this.stream = stream;
}
@Override
public int read() throws IOException {
if (count-- > 0) {
return value;
} else {
count = stream.read();
if (count == -1)
return -1; // end of stream reached
value = stream.read();
if (value == -1)
throw new IOException("malformed RLE stream: "
+ "no value found for count "
+ count);
return value;
}
}
@Override
public void close() throws IOException {
stream.close();
}
}
2 Itérateurs
Partie 1
Il s'agit du patron Composite. On le voit au fait que AddingIterator est lui-aussi un itérateur et qu'il compose le comportment de deux autres itérateurs.
Partie 2
Oui, il est possible et même facile de construire l'itérateur iSum3, de la manière suivante :
Iterator<Integer> iSum3 = new AddingIterator(iSum, i3);
Partie 3
10, 11, 12.
Partie 4
public final class AddingIterator implements Iterator<Integer> {
private final Iterator<Integer> i1, i2;
public AddingIterator(Iterator<Integer> i1,
Iterator<Integer> i2) {
this.i1 = i1;
this.i2 = i2;
}
@Override
public boolean hasNext() {
return i1.hasNext() && i2.hasNext();
}
@Override
public Integer next() {
return i1.next() + i2.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Partie 5
On pourrait utiliser le patron Strategy pour représenter l'opération de combinaison au moyen d'un objet implémentant une interface dotée d'une seule méthode, la méthode de combinaison.
3 Vecteurs creux
Partie 1
Il faut bien penser à copier la table nonZeroEntries reçue en argument, faute de quoi la classe SparseVector n'est pas immutable.
public SparseVector(Map<Integer, Double> nonZeroEntries, int size){
if (size < 0)
throw new IllegalArgumentException("invalid size: "
+ size
+ " (must be >= 0)");
for (int index: nonZeroEntries.keySet()) {
if (! (0 <= index && index < size))
throw new IllegalArgumentException("invalid index: "
+ index
+" (must be in [0;"
+ (size - 1) +"]");
}
this.nonZeroEntries = new HashMap<>(nonZeroEntries);
this.size = size;
}
Partie 2
public int size() {
return size;
}
Partie 3
public double get(int index) {
if (! (0 <= index && index < size))
throw new IllegalArgumentException("invalid index: "
+ index
+" (must be in [0;"
+ (size - 1) +"]");
Double maybeEntry = nonZeroEntries.get(index);
return maybeEntry == null ? 0 : maybeEntry;
}
Il est également possible d'utiliser containsKey pour vérifier la présence de l'élément d'index donné dans la table des éléments non nuls, plutôt que de tirer parti du fait que get retourne null dans ce cas, comme c'est fait ici.