|
Le signe © renvoie à la correction |
Écrivez un programme qui construit une collection triée par ordre croissant contenant n nombres entiers (représentés par des objets Integer) produits au hasard et dont la valeur est comprise entre 0 et 1000. A votre choix, la valeur de n est lue au début de lexécution ou est un argument du programme. Ensuite, ce dernier affiche la collection construite afin quon puisse constater quelle est bien triée.
A. Dans la première version du programme la collection est une sorte de List (par exemple un Vector ou une LinkedList) que vous triez, après la construction, en utilisant une méthode ad hoc de la classe Collections.
B. Dans une deuxième version, la collection est une sorte de Set (cest-à-dire un HashSet ou un TreeSet, mais avez-vous le choix ?) si bien quelle est constamment triée.
Quelle différence importante y a-t-il entre ces deux manières de faire ?
En supposant quune interface CritereSelection a été ainsi définie
public interface CritereSelection { boolean ok(Object x); }
écrivez une classe TestSelection avec une méthode de signature
static Collection selection(Collection source, CritereSelection critere);
qui renvoie la collection formée des éléments de source
qui satisfont le critere donné. Écrivez, également dans la classe TestSelection
, une méthode
main qui
A. Pour commencer, faites en sorte que selection renvoie un objet Vector.
B. Une meilleure solution consisterait à renvoyer une collection de même type que source. A cet effet, constatez que toutes les classes implémentant l’interface Collection ont un constructeur public sans argument et examinez la documentation des méthodes java.lang.Object.getClass() et java.lang.Class.newInstance().
En supposant que vous disposez dune interface telle que
public interface Transformation { Object transfo(Object x); }
programmez une classe ListeTransformable ainsi définie : un objet lt de type ListeTransformable est une liste chaînée (classe LinkedList) possédant en plus une méthode ordinaire (c.-à-d. non statique)
ListeTransformable transforme(Transformation f);
telle que lt.transforme(f) est la liste obtenue en appliquant la transformation f à chaque élément de lt.
A. Définissez la classe ListeTransformable en
utilisant la composition (c.-à-d. un objet ListeTransformable
a un objet LinkedList). Écrivez une méthode main
qui la teste en construisant et en affichant une première ListeTransformable qui contient les 50 premiers entiers et une deuxième ListeTransformable qui contient les carrés de ces nombres : 0, 1, 4, 9, 16...
B. Définissez la classe ListeTransformable en
utilisant lhéritage (c.-à-d. un objet ListeTransformable
est une sorte dobjet LinkedList), avec une méthode main
comme ci-dessus.
C. Quelle manière de faire vous semble préférable ? Citez une situation où la composition serait évidemment préférable.
On vous demande décrire une classe Annuaire pour mémoriser un ensemble de numéros de téléphone et dadresses. Chaque entrée est représentée par une fiche à plusieurs champs : un nom, un numéro et une adresse. La structure des fiches est décrite par une classe Fiche que vous devez écrire.
Écrivez également une classe Annuaire comportant une table associative (Map) qui sera faite dassociations ( un_nom , une_fiche ).
A. Dans un premier temps, la table associative en question sera une instance de la classe HashMap. Écrivez un programme répétant les opérations suivantes
B. On constate que la commande ! produit laffichage des fiches dans un ordre imprévisible. Que faut-il changer dans le programme précédent pour que les fiches apparaissent dans lordre des noms ?
C. [Facultatif] Faites en sorte quà la fin (resp. au début) du programme lannuaire soit enregistré (resp. lu) dans un fichier nommé annuaire.obj. Utilisez des flux ObjectInputStream et ObjectOutputStream (que lon doit créer à partir de flux FileInputStream et FileOutputStream préexistants).
Noubliez pas dautoriser (par un énoncé « implements Serializable ») la « sérialisation » des objets qui doivent être écrits ou lus dans le fichier.
Les applications Java accèdent à un ensemble de propriétés système qui définissent des aspects de leur environnement dexécution, comme la version de la machine Java, le système dexploitation sous-jacent, le répertoire de travail, etc. Ces propriétés sont codées sous la forme de couples de chaînes (clé, valeur), et on les obtient par un appel de la méthode System.getProperties() qui renvoie un objet Properties qui est une sorte de table associative ou Map.
Pour connaître la valeur dune propriété à partir de son nom on utilise System.getProperty(nom)
De manière analogue, une application Java accède à lensemble de variables denvironnement (path, user, etc.) définies au niveau du système dexploitation sous-jacent ; cest encore une table associative, ou Map, quon obtient par un appel de la méthode System.getenv().
Pour obtenir la valeur dune variable denvironnement a partir de son nom on écrit System.getenv(nom).
Écrivez une méthode
static void afficherMap(Map tableAssoc);
qui affiche les éléments dune table associative sous la forme
clé1 --> valeur1
clé2 --> valeur2
etc. Servez-vous en pour obtenir la liste des propriétés système avec leur valeurs, puis des variables denvironnement avec leurs valeurs.
N.B. Properties est une sous-classe de Hashtable, elle-même sous-classe de Dictionary. Ninvestissez pas dans ces deux classes, elles sont obsolètes lune et lautre.
Une arborescence (avec moins de rigueur on dit souvent arbre) est une structure de données formée dun ensemble E et dune relation qui à chaque élément de E sauf un, appelé la racine de larborescence associe un autre élément appelé son père.
Les éléments dune arborescence sont appelés nœuds ; à chaque nœud n est donc associée une liste, éventuellement vide, de nœuds dont n est le père ; on les appelle les fils de n. Lorsquun nœud na pas de fils, on dit que cest une feuille.
A. Écrivez une classe Noeud<E> pour représenter les [nœuds des] arborescences (E représente le type des informations portées par les nœuds). Cette classe doit avoir les méthodes publiques suivantes :
B. Pour essayer la classe Noeud, écrivez un programme qui construit et affiche l’arbre de tous les « mots », sensés ou non, d’au plus trois lettres formés avec les quatre lettres a, b, c, d (il y en 85: le mot vide, puis a, aa, aaa, aab, aba, abb, ..., ddc, ddd).
C. Pour avoir un essai plus intéressant, écrivez un programme qui construit et affiche larborescence des fichiers et répertoires ayant pour racine un répertoire donné.
Indications. Pour vous promener dans les fichiers et répertoires, les méthodes suivantes de la classe java.io.File vous seront utiles : getName(), isDirectory(), listFiles().
Un graphe non orienté G = (S, A) est déterminé par la donnée dun ensemble S, dont les éléments sont appelés les sommets, et un ensemble A de paires de sommets dont les éléments sont appelés arêtes. Étant donnée une arête a = {s1, s2} on dit que s1 et s2 sont les extrémités de a et donc que s1 et s2 sont deux sommets adjacents ou voisins.
On représente souvent S comme un ensemble de points du plan et A comme un ensemble darcs ou segments joignant ces sommets (il découle de notre définition des graphes quil ne peut pas y avoir deux arêtes distinctes ayant les mêmes extrémités).
Dans beaucoup dapplications on associe un poids à chaque arête : par exemple, si le graphe représente un réseau routier, chaque arête correspond à un tronçon de route entre deux carrefours et est naturellement affectée dun poids, la longueur du tronçon :
Il existe plusieurs manières de représenter les graphes. Dans le programme réalisé ici nous allons le faire en associant à chaque sommet s la liste des couples (s, p) où s est un sommet adjacent à s et p le poids de larête correspondante. Par exemple, dans la figure ci-dessus, pour le sommet étiqueté a cette liste est [(f, 5), (b, 3)], pour le sommet b la liste est [(a, 3), (f, 6), (e, 4 ), (c, 1)] et ainsi de suite.
A. Écrivez la classe Voisin dont les instances représentent ces couples (sommet, poids). Faites le plus simplement simple, ce nest quune classe auxiliaire.
Écrivez la classe Sommet dont les instances représentent les sommets du graphe. Elle comporte les méthodes publiques :
Écrivez la classe Graphe qui se comporte comme une table associative (ou « map ») dont les valeurs sont les sommets du graphe et les clés les étiquettes correspondantes. Elle aura les méthodes publiques :
Pour essayer tout cela, écrivez un programme principal qui crée un graphe analogue à celui de la figure ci-dessus et affiche tous les chemins joignant deux de ses sommets.
Indication. Pour lécriture de la fonction tousChemins il est recommandé décrire une fonction auxiliaire
void chemins(Sommet depart, Sommet arrivee, Stack pile);
qui, si le problème nest pas résolu (i.e. si départ nest pas égal à arrivée), parcourt les sommets voisins de départ et se rappelle elle même avec chacun de ces sommets pour nouveau départ. La pile donnée représente le bout de chemin déjà construit ; elle sert à vérifier que le chemin en cours de construction ne boucle pas et à laffichage de la solution le moment venu.
B. Ajoutez à la classe Graphe une méthode publique
void unChemin(String depart, String arrivee)
qui affiche un chemin joignant les sommets indiqués (n’importe quel chemin ; par exemple, le premier trouvé).
C. Écrivez une méthode
void plusCourtChemin(String depart, String arrivee)
qui affiche le plus court chemin joignant les deux sommets indiqués.