1 Une représentation des piles

publicité
Université de Nice-Sophia Antipolis
Algorithmique & Programmation
Deug MIAS-MI 1
2002–2003
TP N 13
Les types abstraits, les piles, les files
Buts :
– montrer comment la notion d’interface en Java permet d’implémenter celle de type abstrait
vue en cours.
– montrer que les objets de Java ressemblent à ce qu’en Cours et TD nous appelons des pointeurs sur des articles 1
– réaliser des implémentations des types abstraits pile et file.
1 Une représentation des piles
Vous trouverez dans les ressources une collection de fichiers que vous devrez examiner avec
le plus grand soin car ils sont destinés à vous servir de modèles pour la suite.
– Stack.java déclare une interface de Java : une interface ressemble à une classe, mais tous
les attributs y sont forcément static et final, il n’y a aucun constructeur et les méthodes
sont toutes abstraites (elles n’ont pas de corps). En fait, il ne s’agit que de l’énumération
des méthodes que doit nécessairement posséder une classe pour avoir le droit de mettre
dans son en-tête implements Stack et pour que ses instances aient donc le droit d’être
déclarées Stack.
– StackA.java déclare une classe qui implémente l’interface Stack avec le triplet d’une
capacité, d’un tableau de cette capacité et d’un indice dans ce tableau. Cela correspond
presque exactement à ce que, dans le Cours et les TD, on aurait probablement déclaré :
type
T_contenu = ?
T_descripteur_de_pile = article
tailleMax : entier
data : tableau 1 .. tailleMax de T_contenu
sommet : 0 .. tailleMax
T_pile = pointeur sur T_descripteur_de_pile
finarticle
– StackB.java déclare une classe qui implémente l’interface Stack avec un chaînage simple.
La classe Cell qui implémente les cellules du chaînage a été déclarée à l’intérieur de la
classe StackB ce qui facilite les choses en permettant que ses attributs, même déclarés
private, soient visibles n’importe où dans StackB. Une telle classe s’appele une classe
emphmembre (elle est un membre, comme les attributs et les méthodes, de sa classe englobante). Dans le Cours ou les TD, on aurait probablement écrit :
type
T_contenu = ???
T_descripteur_de_cellule = article
contenu : T_contenu
suivant : T_cellule
finarticle
1. Il s’agit d’une ressemblance particulièrement intéressante à relever, mais ils ne faut cependant pas croire que les
objets sont exactement des pointeurs sur des articles.
1
T_cellule = pointeur sur T_descripteur_de_cellule
T_descripteur_de_pile = article
tête : T_cellule
finarticle
T_pile = pointeur sur T_descripteur_de_pile
– Les classes EmptyStackException.java et FullStackException.java peuvent être
négligées à la première lecture. Ces fichiers déclarent des classes qui étendent RuntimeException
(exceptions qui peuvent survenir lors de l’exécution) afin d’avoir des exceptions sur mesure.
Vous remarquerez que, si l’exception de pile vide ne fait pas grand chose, l’exception de pile
pleine stocke la taille maximale dans un attribut afin de pouvoir le renvoyer sur demande.
– Stacks.Java décrit une classe exécutable (qui contient une méthode main). Elle teste les
performances comparées des deux implémentations précédentes. Vous remarquerez que
la pile y est toujours déclarée Stack : ce n’est qu’au moment de l’instanciation qu’on
choisit telle ou telle implémentation en choisissant tel ou tel constructeur !
Exercice 1 Allez consuler la documentation de la classe classe Stack de l’API Java et proposez
une troisième implémentation de notre interface Stack qui commencerait 2 :
public class StackC implements Stack {
// Attribut
private java.util.Stack stack ;
// Constructeur
public StackC () {
stack = new java.util.Stack() ;
}
}
Comparez ses performances avec celles des deux implémentations précédentes. Interprétez les
résultats.
2 Une représentation des files d’attente
Sur le modèle de la section précédente, vous allez traiter le problèmes des files d’attente en
écrivant les quatre fichiers Queue.java, QueueA.java, QueueB.java et Queues.java.
Exercice 2 Définir l’interface Queue, proposant les trois méthodes abstraites isEmpty, enqueue
et dequeue. Puis implémentez les files d’attente QueueA en utilisant un tableau circulaire.
Exercice 3 Implémentez les files d’attente QueueB en utilisant une liste chaînée circulaire avec
sentinelle. L’attribut, le constructeur et la classe des cellules vous sont donnés :
public class QueueB implements Queue {
private Cell sentry ;
public QueueB () {
sentry = new Cell(null) ;
sentry.next = sentry ;
sentry.previous = sentry ;
}
class Cell {
private Object content ;
private Cell next, previous ;
Cell (Object o) {
content = o ;
next = previous = null ;
2. On n’utilise pas import mais le chemin explicite, afin d’éviter les conflits de nom entre les deux Stack.
2
}
}
}
Il ne vous reste plus qu’à implémenter les trois méthodes recquises par l’interface Queue. Ce n’est
pas si difficile mais, si vous ne faites pas des dessins soigneux pour comprendre votre systèmes
de références (pointeurs), il est très peu probable que vous y parveniez.
3 Exercices facultatifs
– Comparez les performances de QueueA et QueueB.
– Proposez une troisième implémentation des files d’attente en utilisant une extension de la
classe Vector de l’API Java :
import java.util.Vector ;
public class QueueC extends Vector implements Queue {
// pas de nouvel attribut
public QueueC () {
super() ;
}
/* compléter par les méthodes nécessaires de Queue,
définies au moyen des méthodes héritées de Vector */
}
– Utilisez une pile pour vérifier qu’une expression contenue dans une chaîne est correctement
parenthésée. Vous pourrez utiliser l’algorithme dont le corps est :
variables
i : entier
c : chaîne de caractères
p : pile de caractères
début
lire(c)
initialiser(p)
i
1
boucle
si i > longueur(c) alors sortie boucle finsi
si c[i] = ’ ( ’ alors
empiler(p, ’ ( ’ )
sinonsi c[i] = ’ ) ’ alors
si pilevide(p) alors
sortie boucle
sinon
dépiler(p)
finsi
finsi
i
1
finboucle
{ bilan à votre charge }
fin
– Ajoutez au deux interfaces Stack et Queue une méthode :
public abstract int size () ;
// taille courante de la pile ou de la file d’attente
et, bien sûr, implémentez-la partout où il le faut.
3
Téléchargement