Cours 4.0: Listes. Piles. Interface/Implements



Documents pareils
Programmation Orientée Objet Java

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Programmer en JAVA. par Tama

Java Licence Professionnelle CISII,

Génie Logiciel avec Ada. 4 février 2013

Corrigé des exercices sur les références

Package Java.util Classe générique

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Utilisation d objets : String et ArrayList

Chapitre 10. Les interfaces Comparable et Comparator 1

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Premiers Pas en Programmation Objet : les Classes et les Objets

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Cours 1: Java et les objets

IRL : Simulation distribuée pour les systèmes embarqués

Une introduction à Java

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Programmation avec des objets : Cours 7. Menu du jour

Université Bordeaux 1, Licence Semestre 3 - Algorithmes et struct...

Java Licence Professionnelle CISII,

Développement Logiciel

as Architecture des Systèmes d Information

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Auto-évaluation Programmation en Java

Langage Java. Classe de première SI

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

TP1 : Initiation à Java et Eclipse

ACTIVITÉ DE PROGRAMMATION

RMI le langage Java XII-1 JMF

TD/TP PAC - Programmation n 3

Projet de programmation (IK3) : TP n 1 Correction

Programme Compte bancaire (code)

Exercices INF5171 : série #3 (Automne 2012)

Tp 1 correction. Structures de données (IF2)

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

TD/TP PAC - Programmation n 3

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Remote Method Invocation Les classes implémentant Serializable

Programmation Par Objets

Plan du cours. Historique du langage Nouveautés de Java 7

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Programmation Objet Java Correction

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Cours de Programmation Impérative: Zones de mémoires et pointeurs

INITIATION AU LANGAGE JAVA

Programmation en Java IUT GEII (MC-II1) 1

4. Groupement d objets

Généralités sur le Langage Java et éléments syntaxiques.

Un ordonnanceur stupide

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

INF 321 : mémento de la syntaxe de Java

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java


I. Introduction aux fonctions : les fonctions standards

Cours de Programmation 2

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Objets et Programmation. origine des langages orientés-objet

Introduction au langage C

Java 1.5 : principales nouveautés

Principes des langages de programmation INF 321. Eric Goubault

Chapitre VI- La validation de la composition.

Derrière toi Une machine virtuelle!

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Exercices sur les interfaces

PROGRAMMATION PAR OBJETS

Calcul Parallèle. Cours 5 - JAVA RMI

TD3: tableaux avancées, première classe et chaînes

Introduction à la programmation concurrente

Problèmes liés à la concurrence

Généricité. en Java. (polymorphisme paramétrique) Philippe GENOUD UJF Janvier

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

Notions fondamentales du langage C# Version 1.0

Machines virtuelles fonctionnelles (suite) Compilation ML Java

4. Outils pour la synchronisation F. Boyer, Laboratoire Lig

Classe Interne, Anonyme & Enumération

2. Comprendre les définitions de classes

Cours d initiation à la programmation en C++ Johann Cuenin

Conventions d écriture et outils de mise au point

Apprendre Java en 154 minutes

Threads. Threads. USTL routier 1

F. Barthélemy. 17 mai 2005

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

TP3. Mail. Attention aux fausses manoeuvres lors de ce TP vous pouvez endommager votre mail sur ouindose.

Structures dynamiques Listes chaînées

La JVM. La machine virtuelle Java. La JVM. La JVM

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

OpenPaaS Le réseau social d'entreprise

Introduction au langage Java

Programmation Objet I

Java c est quoi? Java pourquoi?

Aide mémoire UML & Java 1ère partie : Introduction. marc.lemaire@u-cergy.fr

Environnements de développement (intégrés)

Transcription:

Cours 4.0: Listes. Piles. Interface/Implements Olivier Bournez bournez@lix.polytechnique.fr LIX, Ecole Polytechnique 2011-12 Algorithmique

2 Aujourd hui Piles. Files Utilisation des piles et des files Programmer des piles et des files Piles et files dans la bibliothèque JAVA Interface/Implements en JAVA

3 Le type abstrait sac On souhaite considérer une structure de données, que l on va appeler sac, permettant de stocker des Objets. On veut pouvoir: tester si un sac est vide? ajouter un élément dans un sac. retirer un élément d un sac non vide. class Sac {... Sac() {... } //Construire un sac vide boolean EstVide() {... } //Tester si un sac est vide void Ajouter(Objet e) {... } //Ajouter un élément à un sac Objet Enlever() {... } //Enlever un élément d un sac }

4 Les types abstraits permettent de décrire un objet uniquement par ses fonctions de base. de faire abstraction de la réalisation. Un sac peut être implémenté par une liste, par un tableau,... Modifier son implémentation ne modifie pas le reste du programme. La notion d interface, d héritage, et de module sera vue plus avant dans le cours INF431.

5 Files. Piles Les piles et les files sont des sacs. Une pile est un sac LIFO (Last-In First-Out) lorsqu on retire un élément, on récupère toujours le dernier ajouté. Une file est un sac FIFO (First-in First-Out) on retire les éléments dans l ordre de leur insertion.

5 Files. Piles Les piles et les files sont des sacs. Une pile est un sac LIFO (Last-In First-Out) lorsqu on retire un élément, on récupère toujours le dernier ajouté. ajouter se dit empiler (push), retirer se dit dépiler (pop). Une file est un sac FIFO (First-in First-Out) on retire les éléments dans l ordre de leur insertion. ajouter se dit enfiler, retirer se dit défiler.

Piles, Files d entiers class Pile {... Pile() {... } boolean EstVide() {... } int Tete() {...} } void Empiler(int e) {... } int Dépiler() {... } Pile s= new Pile(); class File {... File() {... } boolean EstVide() {... } int Tete() {...} } void Enfiler(int e) {... } int Défiler() {... } File s= new File();

7 Une pile et une file de caractères c b a Sommet de pile Sortie de file Entrée de file c b a

7 Une pile et une file de caractères c b a Sommet de pile Sortie de file Entrée de file c b a s.ajouter( d )

7 Une pile et une file de caractères d c b a Sommet de pile Sortie de file Entrée de file c b a d

7 Une pile et une file de caractères d c b a Sommet de pile Sortie de file Entrée de file c b a d s.ajouter( e )

7 Une pile et une file de caractères e d c b a Sommet de pile Sortie de file Entrée de file c b a d e

7 Une pile et une file de caractères e d c b a Sommet de pile Sortie de file Entrée de file c b a d e s.enlever()

7 Une pile et une file de caractères d c b a Sommet de pile Sortie de file Entrée de file b a d e

7 Une pile et une file de caractères d c b a Sommet de pile Sortie de file Entrée de file b a d e s.ajouter( f )

7 Une pile et une file de caractères f d c b a Sommet de pile Sortie de file Entrée de file b a d e f

7 Une pile et une file de caractères f d c b a Sommet de pile Sortie de file Entrée de file s.enlever() b a d e f

7 Une pile et une file de caractères d c b a Sommet de pile Sortie de file Entrée de file a d e f

8 Aujourd hui Piles. Files Utilisation des piles et des files Programmer des piles et des files Piles et files dans la bibliothèque JAVA Interface/Implements en JAVA

Les files Elles sont présentes dès qu on a besoin d utiliser ou de modéliser une file d attente. par exemple: les impressions dans un système d exploitation sont gérées par une file; dans une simulation d un guichet, on modélisera généralement l arrivée des clients par une file. Sortie de file Entrée de file

Les files Elles sont présentes dès qu on a besoin d utiliser ou de modéliser une file d attente. par exemple: les impressions dans un système d exploitation sont gérées par une file; dans une simulation d un guichet, on modélisera généralement l arrivée des clients par une file. Sortie de file Entrée de file Il existe une théorie des files d attente en évaluation de performances/recherche opérationnelle. 9

10 Les piles Les piles sont des objets informatiques omniprésents: par exemple: les annulations d édition dans un traitement de texte sont gérées par une pile; reconnaître une expression bien parenthésée nécessite une pile; les appels récursifs sont gérés par une pile de récursion; évaluer une expression arithmétique nécessite une pile. Sommet de pile

Analyse syntaxique Reconnaître une expression bien parenthésée avec deux types de parenthèses [ et (. [([])[]] est bien parenthésé. [(]) est mal parenthésé. static boolean BienParenthésé(String s) { Pile p = new Pile () ; for (int i=0; i<s.length(); i++) { char c= s.charat(i); if (c== [ c== ( ) p.empiler(c); else if (c== ] ) { if (!p.estvide() && p.dépiler() [ ) return false;} else if (c== ) ) { if (!p.estvide() && p.dépiler() ( ) return false;}} return p.estvide();} Les méthodes s.length() et s.charat(i) de la classe String retournent la longueur et le caractère numéro i de s.

12 Aujourd hui Piles. Files Utilisation des piles et des files Programmer des piles et des files Piles et files dans la bibliothèque JAVA Interface/Implements en JAVA

13 Programmer des piles et des files Solution 1: avec des listes. Solution 2: avec des tableaux.

14 Une pile avec une liste class Pile { private Liste l; // sommet de la pile Pile() { l=null; } boolean EstVide() { return (l==null); } int Tete() { return l.contenu;} } void Empiler(int e) { l=new Liste(e,l); } int Dépiler() { int c=l.contenu; l=l.suivant; return(c); } l 4 7 3 Le mot clé private permet de garantir qu aucune autre classe ne puisse modifier ou accéder au champ l. Cela permet de garantir qu il n est pas modifié autrement que par les méthodes de la classe Pile.

Gérer les erreurs class Pile { private Liste l; // sommet de la pile Pile() { l=null; } boolean EstVide() { return (l==null); } int Tete() { i f (l==null) throw new Error("Pile Vide"); return l.contenu;} } void Empiler(int e) { l=new Liste(e,l); } int Dépiler() { i f (l==null) throw new Error("Pile Vide"); int c=l.contenu; l=l.suivant; return(c); } throw new Error("Pile Vide") arrête l exécution du programme en lançant (instruction throw) une exception (ici un objet de la classe Error). Affiche: Exception in thread main java.lang.error: Pile Vide en cas d erreur.

Une file avec une liste class File { private Liste in; // entrée de la liste private Liste ou; // sortie de la liste File() { in=out=null; } boolean EstVide() { return (in==null && out==null); } int Tete() { return out.contenu;}... } in out 4 7 3 Le champ out pointe sur la première cellule de liste (pour enlever) in pointe sur la dernière cellule de liste (pour ajouter) 16

17 Enfiler void Enfiler(int i) { if (EstVide()) in = out = new List(i,null); else { in.suivant = new List(i,null); in = in.suivant; }} in out 4 7 3

17 Enfiler void Enfiler(int i) { if (EstVide()) in = out = new List(i,null); else { in.suivant = new List(i,null); in = in.suivant; }} in out 4 7 3 5

17 Enfiler void Enfiler(int i) { if (EstVide()) in = out = new List(i,null); else { in.suivant = new List(i,null); in = in.suivant; }} in out 4 7 3 5

18 Défiler int Défiler() { if (EstVide()) throw new Error("Pile Vide"); int r= out.contenu; out = out.suivant; i f (out==null) in = null; return r; } in out 4 7 3 Ne pas oublier de remettre in à null lorsque la pile est vide.

18 Défiler int Défiler() { if (EstVide()) throw new Error("Pile Vide"); int r= out.contenu; out = out.suivant; i f (out==null) in = null; return r; } in out 4 7 3 Ne pas oublier de remettre in à null lorsque la pile est vide.

19 Une pile avec un tableau On crée un tableau suffisamment grand. On utilise un entier sp, le pointeur de pile, qui compte le nombre d éléments dans la pile. Les éléments d indice inférieur à sp contiennent les éléments de la pile. Les autres, ici en blanc, sont disponibles. 0 6 1 2 2 7 3 0 4 2 5 8 6 0 7 2 8 3 9 4 sp 5 Principe: Tete(): t[sp-1]. Empiler(e): t[sp++] =e. Dépiler(): t[--sp].

20 Une pile avec un tableau class Pile { final static int TAILLE = 100; private int[] t; private int sp; Pile() { t=new int[taille]; sp=0; } boolean EstVide() { return (sp 0); } int Tete() { i f (EstVide()) throw new Error("Pile Vide"); return t[sp-1];} void Empiler(int e) { i f (sp t.length) throw new Error("Pile Pleine"); t[sp++] = e;} int Dépiler() { i f (EstVide()) throw new Error("Pile Vide"); return t[--sp];} }

21 Une pile avec un tableau dynamique private void resize() { int[] newt = new int [2*t.length]; for (int i=0; i<t.length; i++) newt[i] = t[i]; t= newt; } void Empiler(int e) { if (sp t.length) resize(); t[sp++] = e;}

Analyse de complexité Les versions précédentes de Empiler() et Dépiler() fonctionnaient en temps O(1) (temps constant). Maintenant, Empiler() peut provoquer la recopie d un tableau arbitrairement grand, et donc prendre un temps arbitrairement grand. Cependant, Empiler() reste en coût O(1) amorti (coût global ramené au nombre d opérations).

Analyse de complexité Les versions précédentes de Empiler() et Dépiler() fonctionnaient en temps O(1) (temps constant). Maintenant, Empiler() peut provoquer la recopie d un tableau arbitrairement grand, et donc prendre un temps arbitrairement grand. Cependant, Empiler() reste en coût O(1) amorti (coût global ramené au nombre d opérations). Supposons que l on fasse N fois Empiler() ou Dépiler(), et que la taille initiale du tableau soit 2 p0. Dans le pire cas, le tableau est redimensionné p + 1 p0 fois, avec 2 p < N 2 p+1. Coût total dans ce cas: O(2 p0 + 2 p0+1 + + 2 p+1 ) = O(2 p+2 ) < O(4.N) = O(N). Ce qui fait un coût amorti O(1) par élément. En effet, le coût global/ le nombre d éléments est O(N)/N = O(1).

Une file avec un tableau On créer toujours un tableau de taille TAILLE suffisamment grande. On utilise cette fois deux entiers in, et out. Les éléments entre in et out-1 contiennent les éléments de la file. Les autres, ici en blanc, sont disponibles. 0 6 1 2 2 7 3 0 4 2 5 8 6 0 7 2 8 3 9 4 in 3 out 7

Une file avec un tableau On créer toujours un tableau de taille TAILLE suffisamment grande. On utilise cette fois deux entiers in, et out. Les éléments entre in et out-1 contiennent les éléments de la file. Les autres, ici en blanc, sont disponibles. 0 6 1 2 2 7 3 0 4 2 5 8 6 0 7 2 8 3 9 4 in 3 out 7 Variante: on peut supposer le tableau circulaire: les éléments entre in et out-1 modulo TAILLE contiennent les éléments de la file. 0 6 1 2 2 7 3 0 4 2 5 8 6 0 7 2 8 3 9 4 in 8 out 3

Une file avec un tableau class File { final static int TAILLE = 100; private int[] t; private int in,out; File() { t=new int[taille]; in=out=0; } boolean EstVide() { return (in == out); } boolean EstPleine() { return ((out+1) % TAILLE == in);} void Enfiler(int e) { i f (EstPleine()) throw new Error("Pile Pleine"); t[out]=e; out = (out +1) % TAILLE;} int Défiler() { i f (EstVide()) throw new Error("Pile Vide"); int c=t[in]; in = (in+1) % TAILLE; return (c); } 24

25 Aujourd hui Piles. Files Utilisation des piles et des files Programmer des piles et des files Piles et files dans la bibliothèque JAVA Interface/Implements en JAVA

26 Utiliser les bibliothèques JAVA Piles et files sont tellement utilisées qu elles sont proposées dans les classes JAVA standards. Exemple: la classe Stack du package java.util (qui correspond à l implémentation par tableaux dynamiques précédente) pour les piles. Des piles de quoi?

27 Classes génériques Les codes d une pile/file d entiers d une pile/file de réels d une pile/file de chaînes de caractères d une pile/file de piles d une pile/file de files d une pile/file de... se ressemblent beaucoup.

28 Classes génériques Les classes de la bibliothèque JAVA sont en fait génériques. Stack est une classe générique qui prend une classe en argument. Exemple: Stack<String> désigne une pile de chaînes de caractères. Plus généralement, Stack<E> est une pile d objets de la classe E.

Exemple (attention ordre opérations incorrect) import java.util.*; class Traduit { public static void main (String [] args) { Stack<String> p = new Stack<String> () ; for (int i = 0 ; i < args.length ; i++) { String cmd = args[i] ; if (cmd.equals("+") cmd.equals("-") cmd.equals("*") cmd.equals("/")) p.push("(" + p.pop() + cmd + p.pop() + ")"); else p.push(cmd) ; } System.out.println(p.pop()) ; }} Dans les librairies standards, Empiler se dit push, Dépiler se dit pop, EstVide() se dit empty, Tete se dit peek (voir documentation JAVA).

30 Comment créer une pile d entiers On ne peut pas utiliser le type Stack<int>, car int n est pas une classe. Cependant, la bibliothèque JAVA standard fournit une classe appropriée par type scalaire. Par exemple, la classe Integer pour int: La classe Integer est une classe avec un champ private de type int. On convertit un scalaire int en un objet Integer et réciproquement par: public static Integer valueof(int i): du scalaire vers un Integer. public int intvalue(): réciproquement. Il y a des classes semblables (Char, Short, etc.) pour tous les types scalaires (char, short, etc.).

31 Exemple import java.util.* ; class Calc { public static void main (String [] arg) { Stack<Integer> stack = new Stack<Integer> () ;... int i1 = stack.pop().intvalue() ; int i2 = stack.pop().intvalue() ; stack.push(integer.valueof(i2+i1)) ;... } } En fait, le compilateur accepte stack.push(i2+i1), car il fait les conversions int vers Integer tout seul.

32 Files de la bibliothèque La classe LinkedList<C> (package java.util) fait l affaire. Il s agit en fait d une double-ended queue. On peut utiliser les méthodes addfirst et addlast (put) pour ajouter un élément au debut ou à la fin. les méthodes removefirst (get) et removelast pour récupérer le premier ou dernier élément. Le tout en temps constant, par des listes doublement chaînées (voir le poly, section 2.3.3). Il existe d autres classes de la bibliothèque standard avec des noms plus séduisants (comme Queue), mais LinkedList<C> est peut-être la plus pratique.

33 Aujourd hui Piles. Files Utilisation des piles et des files Programmer des piles et des files Piles et files dans la bibliothèque JAVA Interface/Implements en JAVA

34 Définir un type abstrait proprement On veut définir le type abstrait sac class Sac {... Sac() {... } //Construire un sac vide boolean EstVide() {... } //Tester si un sac est vide void Ajouter(int e) {... } //Ajouter un entier à un sac int Enlever() {... } //Enlever un entier d un sac } Pour le faire proprement en JAVA, on peut définir interface Sac { boolean EstVide(); //Tester si un sac est vide void Ajouter(int e); //Ajouter un entier à un sac int Enlever(); //Enlever un entier d un sac }

35 Ce qui permet de l utiliser A ce moment là, sac n est pas une classe, mais on peut l utiliser comme un type... static void count(sac s) { for (int i=0;!s.estvide(); i++) { s.enlever(); }}... sans se préoccuper de l implémentation.

Créer une implémentation On utilise le mot clé implements. Implémentation 1: Implémentation 2: class Pile implements Sac { class File implements Sac { private int[] t; private int sp; Pile() { t=new int[100]; sp=0; } public boolean EstVide() { return (sp 0); } int Tete() {return t[sp-1];} public void Ajouter(int e) { t[sp++] = e;} public int Enlever() { return t[--sp];} }} private int[] t; private int in,out; File() { t=new int[100]; in=out=0;} public boolean EstVide() { return (in == out); } public void Ajouter(int e) { t[out]=e; out=(out +1)% 100;} public int Enlever() { int c=t[in]; in=(in+1) % 100; return c;} }

Intérêts On peut travailler sans se préoccuper de l implémentation. 1. ce qui permet le travail en groupe, ou modulaire. 2. et de remplacer une implémentation par une autre sans modifier le reste du programme. Le compilateur refuse de compiler si une des méthodes de l interface est manquante, et donc aide à vérifier que l implémentation de chacune des fonctionnalités est bien présente. Note: Les méthodes déclarées dans l interface doivent être qualifiées de public.