You are on page 1of 9

Universit Paris Diderot e Licence Informatique

Programmation Oriente Objet e Anne 2008-2009 e

TP n2 - Correction
Piles, Tri et Entrepot
Dans ce TD on va faire un simple exercice de programmation avec des classes. On en protera galement pour commencer ` se familiariser avec lenvironnement de dveloppement eclipse. e a e Eclipse, comme emacs, permet dcrire des chiers .java, mais il a beaucoup plus de fonctione nalits, qui rendent la programmation plus rapide et organise, et permettent de trouver les e e erreurs et de tester les programmes plus facilement. Vous pouvez commencer ` utiliser eclipse comme diteur, et dcouvrir au fur et ` mesure ses a e e a fonctionnalits. Lancez ecplise ` partir dun terminal. Choisissez un rpertoire ` utiliser comme e a e a workspace par exemple POO. Crez un projet java TP2. Cela crera un rpertoire TP2 e e e qui contient les chiers .java et les chiers .class Eclipse vous permet de compiler et excuter vos programmes sans passer par le termie nal. Une br`ve introduction ` eclipse, ralise par Julien Cervelle, peut tre consulte ` : e a e e e e a www.enseignement.polytechnique.fr/informatique/profs/Julien.Cervelle/eclipse/ Un cours facultatif ddi aux environnements de dveloppement sera galement disponible au e e e e deuxi`me semestre. e Dans les exercices qui suivent, on va utiliser la classe Scanner, qui a et introduite ` partir e a de la version java 1.5.0. Elle simplie la lecture de donnes sur lentre standard (clavier) ou e e dans un chier. Nous parlerons ici simplement de la lecture au clavier. Pour utiliser la classe Scanner, il faut dabord limporter : import java.util.Scanner; Ensuite il faut crer un objet de la classe Scanner : e Scanner sc = new Scanner(System.in); Pour rcuprer les donnes, il faut faire appel sur lobjet sc aux mthodes dcrites ci-dessous. e e e e e Ces mthodes parcourent la donne suivante lue sur lentre et la retourne : e e e String next() : donne de la classe String qui forme un mot, e String nextLine() : donne de la classe String qui forme une ligne, e boolean nextBoolean() : donne boolenne, e e int nextInt() : donne enti`re de type int, e e double nextDouble() : donne relle de type double. e e Il peut tre utile de vrier le type dune donne avant de la lire : e e e boolean hasNext() : renvoie true sil y a une donne ` lire, e a boolean hasNext(String pattern) : renvoie true si la prochaine donne ` lire forme le e a mot pattern, boolean hasNextLine() : renvoie true sil y a une ligne ` lire, a boolean hasNextBoolean() : renvoie true sil y a un boolen ` lire, e a boolean hasNextInt() : renvoie true sil y a un entier ` lire, a boolean hasNextDouble() : renvoie true sil y a un double ` lire. a Il existe dautres mthodes de la classe Scanner. Si cela vous intresse, allez consulter lAPI e e de java. Dans les exercices que suivent on utilisera la classe scanner pour les saisies au clavier.

Exercice 1 [Piles] Ecrire une classe implantant une pile dlments. On consid`re quun lment ee e ee de pile encapsule une valeur enti`re. e 1. Dnir la classe ElementPile qui reprsente un lment dune pile. Les attributs de cette e e ee classe seront privs. Dnir les constructeurs et les accesseurs de cette classe. e e 2. Comment reprsenter la pile vide ? e 3. Dnir la classe Pile. Le constructeur de cette classe construira la pile vide. e 4. Dnir une mthode permettant de tester si une pile est vide. e e 5. Dnir la mthode empile(ajoute un lment au sommet de la pile) e e ee 6. Dnir la mthode depile (retourne le sommet et le retire de la pile) e e 7. Dnir la mthode sommet (retourne le sommet de la pile sans le retirer) e e 8. Dnir dans la classe Pile la mthode affiche qui ache le contenu dune pile, sans la e e modier. Tester la cration dune pile et sa manipulation en empilant puis dpilant divers lments... e e ee
Correction : dbut Pile.java e

public class Pile { private int pos; // position dans le tableau private ElementPile [] p; public Pile () { // creation dune pile vide de taille 10 p = new ElementPile[10]; pos = 0; } public Pile (int taille) { // creation dun pile vide de taille donnee p = new ElementPile[taille]; } public void empile (ElementPile e) { if (pos == p.length) { // plus dexpace ElementPile[] tmp = new ElementPile[p.length+10]; for (int i = 0; i < p.length; i++) tmp[i] = p[i]; p = tmp; } p[pos++] = e; } public ElementPile depile () { return p[--pos]; } public ElementPile sommet () { return p[pos-1]; } public boolean estVide () { return pos == 0; } public void affiche () { System.out.print("Pile: ["); for (int i = pos-1; i >= 0; i--) p[i].affiche ();

System.out.println (" ]"); } } n Pile.java dbut ElementPile.java e public class ElementPile { private int valeur; public ElementPile () { this.valeur = 0; } public ElementPile (int valeur) { this.valeur = valeur; } public int getValue () { return valeur; } public void affiche () { System.out.print (" "+valeur); } } n ElementPile.java

Exercice 2 [Tri par insertion et piles] Ecrire un programme de tri par insertion dun ensemble de nombres entiers. Les donnes sont stockes dans une pile A et le programme doit retourner e e une pile B contenant ces nombres tris avec le minimum au sommet de la pile. Lalgorithme e propos est le suivant : on utilise une pile C qui est vide au dbut. Tant que la pile A nest pas e e vide, on consid`re les deux cas suivants : e si la pile B est vide ou si llment au sommet de A est plus petit que celui de B : ee on retire llment au sommet de la pile A pour empiler dans la pile B, puis si la pile C ee nest pas vide on retire tous les lments de la pile C pour empiler dans la pile B. ee sinon : on deplace llment au sommet de la pile B ` la pile C. ee a Dnir une classe Tri qui contient trois piles A, B et C, une mthode tri(Pile A, pile B, Pile C) e e et la mthode main(). La pile A peut tre construite ` partir dun tableau dentiers en utilisant e e a la mthode empile. Tester avec la pile A = {4, 3, 2, 5, 8, 2, 6, 9, 3}. e
Correction : public class Tri { private Pile A, B, C; private void tri () { while (!A.estVide()) { if (B.estVide() || B.sommet().getValue() > A.sommet().getValue()) { B.empile(A.depile()); while (!C.estVide()) B.empile(C.depile()); dbut Tri.java e

} else C.empile(B.depile()); } } public Pile tri(Pile A, Pile B, Pile C) { this.A = A; this.B = B; this.C = C; tri(); return B; } } n Tri.java

Exercice 3 Soit la classe Produit dnie par un nom, un prix et le nombre de jours restant e avant premption du produit. e Soit la classe Entrepot dnie par un ensemble de produits et le nombre de produits prims. e e e Lensemble sera vu comme une pile. Vous aurez par ailleurs ` utiliser les mthodes de la classe a e Pile. La classe Pile doit tre modie pour grer les objet Produit On appelera cette modie e e cation PileEntrepot 1. Ecrire la mthode construitEntrepot qui construit un ensemble ` partir de donnes e a e entres au clavier. e 2. Ecrire la mthode trie qui trie un ensemble suivant la date de premption en plaant en e e c haut de la pile le produit dont le nombre de jour avant premption est le plus faible (ce e nombre peut tre ngatif). e e 3. Ecrire la mthode suppression qui te de lensemble tous les produits prims et renvoie e o e e la somme perdue. 4. Ecrire les mthodes qui ralisent lunion, union, et lintersection, intersection, tries de e e e deux ensembles tris. Attention ` la valeur de la variable comptant le nombre de produits e a prims. e e
Correction : class Produit { private String nom; private double prix; private int peremption; Produit(String name, double price, int expire){ nom = new String(name); prix = price; peremption = expire; } Produit(Produit e){ nom = new String(e.nom); prix = e.prix; peremption = e.peremption; } dbut Produit.java e

int getValue(){ return peremption; } double getPrix(){ return prix; } boolean egale(Produit p){ return((nom.equals(p.nom)) && (prix == p.prix) && (peremption == p.peremption)); } public void affiche () { System.out.println("nom: "+nom+", prix: "+prix+", peremption: "+peremption); } } n Produit.java dbut Entrepot.java e import java.util.*; import java.io.*; class Entrepot{ PileEntrepot ensemble; int perime; Entrepot(){ ensemble = new PileEntrepot(); perime = 0; } void construitEntrepot(){ Scanner sc = new Scanner(System.in);

System.out.println("Entrer les produits (nom prix peremption) et taper stop lorsque vous avez te while(!(sc.hasNext("stop"))){ ensemble.empile(new Produit(sc.next(),sc.nextDouble(),sc.nextInt())); if(ensemble.sommet().getValue()<=0) perime++; } } void tri(){ TriEntrepot t = new TriEntrepot(); ensemble=t.tri(ensemble, new PileEntrepot(),new PileEntrepot()); } double suppression(){ double sommePerdue = 0; while(ensemble.sommet().getValue()<=0){ sommePerdue += ensemble.depile().getPrix(); perime++; }

return sommePerdue; } Entrepot union(Entrepot e){ PileEntrepot temp=new PileEntrepot(); Entrepot res=new Entrepot(); while(!(ensemble.estVide()) && !(e.ensemble.estVide())){ if(ensemble.sommet().egale(e.ensemble.sommet())){ temp.empile(ensemble.depile()); e.ensemble.depile(); } else if(ensemble.sommet().getValue() < e.ensemble.sommet().getValue()) temp.empile(ensemble.depile()); else temp.empile(e.ensemble.depile()); res.perime++; } if(ensemble.estVide()) while(!(e.ensemble.estVide())){ temp.empile(e.ensemble.depile()); res.perime++; } else while(!(ensemble.estVide())){ temp.empile(ensemble.depile()); res.perime++; } while(!(temp.estVide())) res.ensemble.empile(temp.depile()); return res; } Entrepot intersection(Entrepot e){ PileEntrepot temp=new PileEntrepot(); Entrepot res=new Entrepot(); while(!(ensemble.estVide()) && !(e.ensemble.estVide())){ if(ensemble.sommet().egale(e.ensemble.sommet())){ temp.empile(ensemble.depile()); res.perime++; } else if(ensemble.sommet().getValue() < e.ensemble.sommet().getValue()) ensemble.depile(); else e.ensemble.depile(); } while(!(temp.estVide())) res.ensemble.empile(temp.depile()); return res;

} void affiche(){ ensemble.affiche(); } public static void main(String[] args){ Entrepot e = new Entrepot(), f = new Entrepot(), g = new Entrepot(); e.construitEntrepot(); e.affiche(); e.tri(); e.affiche(); System.out.println("somme perdue: "+e.suppression()); e.affiche(); f.construitEntrepot(); f.tri(); System.out.println("union: "); e=e.union(f); e.affiche(); System.out.println("perime: "+e.perime); g.construitEntrepot(); g.tri(); g.affiche(); System.out.println("intersection: "); e=e.intersection(g); e.affiche(); System.out.println("perime: "+e.perime); } } n Entrepot.java dbut PileEntrepot.java e public class PileEntrepot { private int pos; // position dans le tableau private Produit [] p; public PileEntrepot () { // creation dune pile vide de taille 10 p = new Produit[10]; pos = 0; } public PileEntrepot (int taille) { // creation dun pile vide de taille donnee p = new Produit[taille]; } public void empile (Produit e) { if (pos == p.length) { // plus dexpace Produit[] tmp = new Produit[p.length+10]; for (int i = 0; i < p.length; i++) tmp[i] = p[i]; p = tmp; } p[pos++] = e; } public Produit depile () { return p[--pos];

} public Produit sommet () { return p[pos-1]; } public boolean estVide () { return pos == 0; } public void affiche () { System.out.print("Pile: ["); for (int i = pos-1; i >= 0; i--) p[i].affiche (); System.out.println (" ]"); } } n PileEntrepot.java

Exercice 4 [Jeu des Tours de Hanoi] Pour ceux qui ont encore du temps Etant donn trois piles, et n disques de tailles direntes empils sur la premi`re, les plus e e e e petits au dessus des plus grands : Un dplacement consiste ` choisir une pile A non vide, et ` enlever le disque au sommet pour le e a a mettre au sommet dune autre pile B, si le sommet de cette pile nest pas un disque plus petit (sinon, le dplacement est impossible). e On veut dplacer tous les disques de la premi`re pile sur la seconde, en se servant de la derni`re. e e e Lalgorithme propos est le suivant : Pour dplacer n disques de la pile A sur la pile C en e e utilisant la pile B, on dplace (rcursivement) n 1 disques de A vers B, puis on dplace le e e e disque restant sur le sommet de la pile A vers la pile C, et on dplace (rcursivement) n 1 e e disques de B vers C. Dnir une classe Hanoi qui reprsente le jeu : trois piles et le nombre de disques. Dnir le e e e constructeur qui initialise le jeu ` partir dun nombre de disques ` empiler et initialise les piles a a dans la situation de dpart. Dnir la mthode affiche qui ache le contenu des piles. Dnir la e e e e mthode prive deplace et la mthode joue qui lance le jeu. Enn, dnir la mthode statique e e e e e main qui ` partir dun entier saisi en ligne de commande initialise et lance le jeu. a Pour visualiser plus agrablement le droulement du jeu, modier la mthode deplace e e e an dacher ltat du jeu apr`s chaque dplacement. On vous propose dutiliser une classe e e e Afficheur qui propose un achage un peu labor et quelques options pour le droulement du e e e jeu. Modier la classe Hanoi en ajoutant un champ de type Afficheur. Le constructeur devra prendre en param`tre un objet de ce type et laecter a votre champ. Remplacer le contenu de e la mthode affiche en eectuant simplement un appel ` la mthode afficher de lAfficheur e a e qui prend en param`tre les trois piles puis le nombre de disques. Compiler le tout et lancer le e jeu en excutant le main de la classe Afficheur. e
Correction : public class Hanoi { private Afficheur aff; private Pile A, B, C; private int nbDisques; dbut Hanoi.java e

public Hanoi (int nbDisques, Afficheur aff) { this.aff = aff; this.nbDisques = nbDisques; A = new Pile(); B = new Pile (); C = new Pile (); for (int i = nbDisques; i > 0; i--) A.empile(new ElementPile (i)); } public void affiche () { aff.affiche(A, B, C, nbDisques); } private void deplace (Pile src, Pile dest, Pile tmp, int n) { if (n > 0) { deplace(src, tmp, dest, n-1); dest.empile(src.depile()); affiche(); deplace(tmp, dest, src, n-1); } } public void joue () { deplace (A, B, C, nbDisques); } } n Hanoi.java

You might also like