ITI 1521. Introduction à l`informatique II

publicité
ITI 1521. Introduction à l’informatique II
Laboratoire 9
Hiver 2016
Objectifs d’apprentissage
• Concevoir une liste doublement chaînée possédant aussi un noeud factice
• Modifier l’implémentation d’une liste chaînée afin d’y ajouter des méthodes.
• Résoudre des problèmes exigeant une bonne compréhension des interfaces.
OrderedStructure
Pour ce laboratoire, vous devez créer une implémentation de l’interface OrderedStructure à l’aide de
noeuds doublement chaînés et d’un noeud factice. L’interface OrderedStructure déclare les méthodes
suivantes.
• int size() ;
• boolean add(Comparable obj) ;
• Object get(int pos) ;
• void remove(int pos).
Consultez les notes du cours ainsi que les Figures 1, 2, 3, et 4 pour des exemples de liste doublement chaînées
avec un noeud factice.
Les implémentations de cette interface doivent sauvegarder les éléments en ordre croissant. L’ordre des
éléments est défini par l’implémentation de la méthode compareTo(Object other) que déclare l’interface
Comparable. Les classes Integer et String implémentent toutes les deux cette interface et peuvent donc
servir pour vos tests.
IMPORTANT : puisque l’objectif principal du laboratoire est de bien maîtriser les concepts
liés à l’implémentation des listes chaînées, par souci de simplicité, nous n’utiliserons pas le
concept de type générique («generics»). Ainsi, 1) le compilateur produira quelques avertissements. Mais surtout, 2) les utilisateurs de la méthode get devront forcer une conversion de
type puisque la valeur de retour est de type Object. Il y a à la fin du laboratoire un exercice
(optionnel) où vous devez produire un type générique. La solution sera publiée la semaine
prochaine.
Fichiers
• OrderedStructure.java
• Documentation
1
1
OrderedList
1. Créez une implémentation de l’interface OrderedStructure. L’implémentation, OrderedList, doit
utiliser des noeuds doublement chaînés, ainsi qu’un noeud factice. La classe doit posséder une référence
head vers le noeud factice. De plus, l’implémentation doit lancer toutes les exceptions nécessaires. Voir
OrderedStructure.
(a) Nous allons développer cette implémentation étape par étape, de haut en bas. C’est-à-dire que
nous allons d’abord implémenter les éléments de haut niveau (variables d’instance, classe imbriquée statique, et des coquilles pour chacune des méthodes). Une fois tout ça en place, nous
implémenterons le corps des méthodes, une à une.
Premièrement, vous devez créer une définition initiale. Pour l’instant, nous ignorons l’implémentation des méthodes afin de nous concentrer sur les variables et la nécessité d’une classe « static »
imbriquée afin de représenter les noeuds de la liste. Pour satisfaire les exigences du compilateur,
toutes les méthodes de l’interface OrderedStructure doivent être déclarées. La classe doit donc
contenir une classe Node, les variables d’instance et des déclarations vides pour chacune des
méthodes de l’interface.
Le compilateur n’acceptera pas des déclarations vides pour les méthodes retournant une valeur.
Vous pourriez inclure un énoncé de retour bidon, retourner la valeur -99 pour la méthode size,
sachant que cet énoncé sera remplacé par une implémentation complète éventuellement.
Cependant, il se peut que vous oubliiez de faire ces changements et l’ensemble de la classe deviendrait difficile à déboguer. Pour cette raison, je préfère créer une définition initiale ne contenant
que l’énoncé suivant.
throw new U n s u p p o r t e d O p e r a t i o n E x c e p t i o n ( " not implemented y e t ! " ) ;
Ça nous permet de compiler la classe et de travailler sur l’implémentation des méthodes une à une.
Toute tentative d’utiliser une méthode qui n’a pas encore d’implémentation sera signalée par une
exception ! Vous pouvez demander des explications supplémentaires à votre aide à l’enseignement
si nécessaire.
Créez une classe test, OrderedListTest. Pour l’instant, elle ne contient qu’une méthode principale déclarant une variable de type OrderedList, désignant un objet OrderedList. (Vous pouvez
utiliser JUnit si vous le souhaitez.)
Assurez vous que l’implémentation partielle comprenne tous les éléments ci-haut et qu’elle compile
parfaitement. Lorsque ce sera fait, vous pouvez procéder à la prochaine étape, l’implémentation
de la méthode size.
Fichiers
• OrderedStructure.java
• OrderedList.java
• OrderedListTest.java
(b) Implémentez la méthode size(), remplacez l’énoncé throw par une implémentation itérative,
traversant la liste et comptant ses éléments. Ajoutez un test à la classe test afin de vous assurer
que la méthode fonctionne pour la liste vide. Nous ajouterons d’autres tests lorsque nous aurons
une méthode add.
Fichiers
• OrderedStructure.java
• OrderedList.java
• OrderedListTest.java
2
(c) Implémentez la méthode boolean add(Comparable obj) ; elle ajoute un élément en ordre
croissant selon l’ordre naturel imposé par la classe de l’objet (i.e. sa méthode compareTo).
Retourne true si l’élément a été ajouté à cette liste ordonnée, et false sinon.
(d) Ajoutez quelques tests afin de valider la méthode add. Il sera difficile d’évaluer la méthode proprement, mais au moins la taille de la liste devrait s’accroître à mesure que des éléments sont
ajoutés à la liste.
(e) Implémentez Object get(int pos). Cette dernière retourne l’élément se trouvant à la position
spécifiée de cette liste ordonnée ; le premier élément se trouve à la position 0. Cette opération ne
doit pas transformer la liste ;
(f) Ajoutez des tests afin de valider les méthodes get et add. Nous sommes maintenant en bien
meilleure position pour évaluer les méthodes add, get et size. En particulier, nous pouvons
ajouter des éléments, utiliser une boucle afin d’accéder aux éléments, un à un, à l’aide de la
méthode get. Assurez-vous que toutes les méthodes fonctionnent bien avant de poursuivre.
Fichiers
• OrderedStructure.java
• OrderedList.java
• OrderedListTest.java
(g) Implémentez void remove(int pos) ; Retire l’élément à la position spécifiée de cette liste ordonnée ; le premier élément se trouve à l’index 0.
(h) Ajoutez des tests afin de valider la méthode remove. Assurez-vous que cette méthode fonctionne
(ainsi que les autres) avant de poursuivre.
Fichiers
• OrderedStructure.java
• OrderedList.java
• OrderedListTest.java
Nous avons maintenant une implémentation complète de l’interface OrderedStructure.
2. Ajoutez la méthode d’instance void merge(OrderedList other) qui ajoute tous les éléments de la
liste other à cette liste tout en préservant l’ordre des éléments. Par exemple, si a et b sont deux listes
ordonnées telles que a contient “D”, “E” et “G”, et b contient “A”, “C”, “D” et “F”, alors l’appel
a.merge(b) transforme a de sorte qu’elle contient maintenant les éléments suivants “A”, “C”, “D”,
“D”, “E”, “F” et “G” ; b demeure inchangée par cet appel.
Cet exercice a pour but d’apprendre à traverser et transformer des listes doublement chaînées. Ainsi,
vous ne devez pas utiliser des méthodes auxiliaires, en particulier, n’utilisez pas la méthode add !
Votre implémentation doit traverser les deux listes et insérer les éléments (valeurs) de l’autre liste dans
celle-ci ; en ordre croissant. Rappelez-vous qu’il est préférable de développer ces habiletés
maintenant, plutôt qu’à l’examen final !
Fichiers
• OrderedStructure.java
• OrderedList.java
• OrderedListTest.java
3. Sujet avancé et optionnel Utilisez votre implémentation de la classe OrderedList comme point de
départ afin de créer un type générique («generics») qui réalise l’interface OrderedStructure suivante :
3
public i n t e r f a c e O r d e r e d S t r u c t u r e <T extends Comparable<T>> {
int s i z e ( ) ;
boolean add (T elem ) throws I l l e g a l A r g u m e n t E x c e p t i o n ;
T g e t ( i n t pos ) throws IndexOutOfBoundsException ;
void remove ( i n t pos ) throws IndexOutOfBoundsException ;
}
L’un des avantages marqués de cette implémentation sera que tous les éléments de la liste auront le
même type. Ce qui est très important pour la méthode compareTo.
• OrderedStructure.java
• OrderedList.java
• OrderedListTest.java
2
Quiz (1 point)
Pour l’implémentation de l’interface List à l’aide d’un tableau, ArrayList.
1. Les insersions aux positions intermédiaires de la liste sont toujours rapides.
2. L’ajout au début de la liste est toujours rapide.
3. Le retrait d’un élément est toujours rapide.
4. Consulter les positions intermédiaires de la liste est toujours rapide.
Inscrivez votre réponse à la question ci-dessus dans le champ Soumission : de la page de soumission du
devor (voir ci-dessous) ;
• https://uottawa.blackboard.com/
Appendice
l
head
size
0
Figure 1 – Une liste vide.
Dernière modification : 21 mars 2016
4
l
B
head
size
1
Figure 2 – Une liste contenant un seul élément.
l
D
B
head
size
2
Figure 3 – Une liste contenant deux éléments.
l
B
D
head
size
3
Figure 4 – Une liste contenant trois éléments.
5
F
Téléchargement