Plan
Langage Java
• Les classes Algorithmique
• Listes, piles, files
Classes
Les classes sont les blocs de base d'un programme Java. Une classe définit un type non primitif et
contient
• des variables
• des méthodes
• du code d'initialisation
• d'autres classes
public class CarreMagique {
final static int N = 100;
static int a[][] = new int[N][N];
static int n;
// Méthodes
static void Init(int n) { . . . }
static void Magique(int n) { . . . }
}
Constructeurs
Les constructeurs d'une classe sont les méthodes, de même nom que la classe, qui permettent de créer des objets. Les constructeurs sont appelés par new.
Point z = new Point(2, 3);
public class Point { int x;
int y;
Point(int abs, int ord) { x = abs;
y = ord;
} }
Objets
• Un objet est une instance d ’une classe.
• Une variable de type non primitif est une référence (ou adresse).
• Déclaration d’une référence ≠ Création d’un objet !
• Copier un objet ≠ copier une référence !
Point z, t;
z = new Point(2, 3);
t = z; //copie de référence z.x = 0;
System.out.println(t.x);
Constructeurs (2)
Java définit un constructeur par défaut. Les autres constructeurs ont le même nom (celui de la classe), mais diffèrent par le type de leurs arguments.
class Affiche
{ Affiche(int x)
{ System.out.println ("L'entier " + x);
} Affiche(float x)
{ System.out.println ("Le réel " + x);
} }
Initialisation des tableaux
new initialise les composants d'un tableau à la valeur par défaut du type du tableau.
Les types numériques sont initialisés à 0, les booléens à false, les types non primitifs à null.
Piège! Les éventuels constructeurs de
type ne sont pas appelés.
Exemple
public class Complexe {
int x;
int y;
public static void main(String args[]) {
Complexe z = new Complexe();
Complexe[] T = new Complexe[3];
System.out.println(z.x); // 0 System.out.println(z.y); // 0 System.out.println(T[1].x);
/* java.lang.NullPointerException
at Complexe.main(Compiled Code)
at com.mw.Exec.run(Compiled Code) */
} }
Listes chaînées
public class Liste {
int contenu;
Liste suivant;
Liste(int x, Liste a) {
contenu = x;
suivant = a;
} }
v
1v
2v
3v
4…
Création
static Liste FaireLvide() {
return null;
}
Opérations sur les listes
boolean EstLvide(Liste a) {
return a == null;
}
static Liste ajouter (int x, Liste a) {
return new Liste (x, a);
}
static Liste LCarres(int n) /* Carres */
{
Liste a;
a = FaireLvide();
for (int i = n; i >= 1; --i) a = ajouter(i * i, a);
return(a);
}
Initialisation d'une liste
Recherche dans une liste
static boolean recherche(int x, Liste a) {
while (a != null) {
if (a.contenu == x) return true;
a = a.suivant;
}return false;
}
// Version récursive :
static boolean rechercheRec(int x, Liste a) {
if (a == null) return false;
else if (a.contenu == x) return true;
else
return rechercheRec(x, a.suivant);
}
Recherche dans une liste
static boolean rech2(int x, Liste a) {
return (a != null) &&
((a.contenu == x) || rech2(x, a.suivant));
}
static void imprimer (Liste a) {
for (Liste b = a; b != null; b = b.suivant) System.out.print(b.contenu + " ");
System.out.println();
}
Affichage d'une liste
Longueur d'une liste
static int longueurRec(Liste a) {
if (a == null) return 0;
else
return 1 + longueurRec(a.suivant);
}
static int longueur(Liste a) {
int longueur = 0;
while (a != null) {
++longueur;
a = a.suivant;
}
return longueur;
}
// Version récursive. On modifie la liste a static Liste supprimerR(int x, Liste a)
{ if (a!= null)
if (a.contenu == x) a = a.suivant;
elsea.suivant = supprimerR(x, a.suivant);
return a;
}
Suppression dans une liste
// Version récursive. On conserve la liste a static Liste supprimerR2(int x, Liste a)
{ if (a == null) return null;
else if (a.contenu == x) return a.suivant;
elsereturn new Liste(a.contenu,
supprimerR2(x, a.suivant));
}
Suppression dans une liste
// Version itérative. On modifie la liste a static Liste supprimer(int x, Liste a)
{ if (a != null)
if (a.contenu == x) a = a.suivant;
else{
Liste b = a;
while (b.suivant != null &&
b.suivant.contenu != x) b = b.suivant;
if (b.suivant != null)
b.suivant = b.suivant.suivant;
return a;} }
static Liste cons(int x, Liste a) // ajouter {
return new Liste(x, a);
}
static int head(Liste a) // tête de liste {
if (a == null)
erreur("Head d'une liste vide.");
return a.contenu;
}
static Liste tail(Liste a) // queue de liste {
if (a == null)
erreur("Tail d'une liste vide.");
return a.suivant;
}
Manipulation des listes
static Liste append(Liste a, Liste b) { if (a == null)
return b;
elsereturn ajouter(a.contenu,
append(a.suivant, b));
}
static Liste nConc(Liste a, Liste b) { if (a == null)
return b;
else{
Liste c = a;
while (c.suivant != null) c = c.suivant;
c.suivant = b;
return a;
} }
Manipulation des listes
static Liste nReverse (Liste a) {
Liste b = null;
while (a != null) {
Liste c = a.suivant;
a.suivant = b;
b = a;
a = c;
}
return b;
}
// Sans modifier la liste :
static Liste reverse (Liste a) {
if (a == null) return a;
elsereturn append(reverse (a.suivant), ajouter ((a.contenu), null));
}
static Liste inserer(int v, Liste a) { Liste b = a;
while (b.suivant != a &&
v > head(b.suivant)) b = b.suivant;
b.suivant = ajouter(v, b.suivant);
a.contenu = head(a) + 1;
return a;
}
Insertion dans une liste triée
On utilise ici une liste circulaire gardée.
Le contenu de la première cellule contient le nombre d'éléments de la suite (ou autre chose) et le champ
suivant de la dernière cellule contient
l'adresse de la première.
Piles
Une pile est une liste où les insertions et les suppressions se font toutes du même coté.
class Pile {
final static int maxP = 10;
int hauteur ; Element[] contenu;
Pile() {
hauteur = 0;
contenu = new Element[maxP];
} }
Piles
static void fairePileVide(Pile p) {
p.hauteur = 0;
}
static boolean estVide(Pile p) {
return p.hauteur == 0;
}
static boolean estPleine(Pile p) {
return p.hauteur == maxP;
}
static void ajouter(Element x, Pile p) { p.contenu[p.hauteur] = x;
++p.hauteur;
}
Manipulation des piles
// A compléter avec des exceptions static Element valeur(Pile p)
{
return p.contenu[p.hauteur -1];
}
static void supprimer(Pile p) { --p.hauteur;
}
Files
Une file est une structure où les insertions se font en queue et les suppressions en tête. La valeur de la file est par convention l'élément de tête.
On peut l'implanter à l'aide d'un
tableau circulaire (cf poly) ou à
l'aide d'une liste munie de deux
pointeurs fin et début.
Files
public class File {
final static int MaxF = 100;
int debut;
int fin;
boolean pleine, vide;
int contenu[];
File() // Constructeur {
debut = 0;
fin = 0;
pleine = false;
vide = true;
contenu = new int[MaxF];
} ...
static void faireFileVide(File f) {
f.debut = 0;
f.fin = 0;
f.pleine = false;
f.vide = true;
}
static void ajouter(int x, File f) {
if (f.pleine)
Erreur ("File Pleine.");
f.contenu[f.fin] = x;
f.fin = Successeur(f.fin);
f.vide = false;
f.pleine = (f.fin == f.debut);
}
Opérations sur les files
Suppression dans une file
static void supprimer (File f) {
if (f.vide)
Erreur ("File Vide.");
f.debut = Successeur(f.debut);
f.vide = (f.fin == f.debut);
f.pleine = false;
}
Evaluation des
expressions arithmétiques
• Expressions arithmétiques en notation préfixée :
- n (n entier naturel) est une expression préfixée
- Si e et f sont des expressions préfixées, alors
+ e f - e f * e f
sont des expressions préfixées Exemple
* * + 5 3 - 2 3 * 2 2
[(5 + 3) * (2 - 3)] * (2 * 2)
La classe Element
// Evaluation des expressions préfixées class Element
{ boolean estSymbole;
int valeur;
char valsymb;
Element(boolean b, int v, char c) { estSymbole = b;
valeur = v;
valsymb = c;
}
public String toString() {
return (estSymbole + ", " + valeur +
", " + valsymb);
} }
La classe ExpressionPrefixe
public class ExpressionPrefixe {
static int calculer (char a, int x, int y) {
switch(a) {
case '+' : return x + y;
case '*' : return x * y;
}
return -1;
}
static void inserer (Element x, Pile p){...}
static int evaluer(Element[] u){...}
public static void main(String args[]){...}
}
static void inserer (Element x, Pile p) {
Element y, z;
if (Pile.estVide(p) || x.estSymbole ||
Pile.valeur(p).estSymbole) Pile.ajouter(x,p);
else {
y = Pile.valeur(p);
Pile.supprimer(p);
z = Pile.valeur(p);
Pile.supprimer(p);
x.valeur = calculer(z.valsymb,
x.valeur, y.valeur);
inserer(x, p);
} }
static void insererIter (Element x, Pile p) {
Element y, z;
while (!(Pile.estVide(p) || x.estSymbole ||
Pile.valeur(p).estSymbole)) {
y = Pile.valeur(p);
Pile.supprimer(p);
z = Pile.valeur(p);
Pile.supprimer(p);
x.valeur = calculer(z.valsymb, x.valeur, y.valeur);
}
Pile.ajouter(x,p);
}
Evaluation des
expressions arithmétiques
static int evaluer(Element[] u) {
Pile p = new Pile();
for (int i = 0; i < u.length ; ++i) {
insererIter(u[i], p);
}
return Pile.valeur(p).valeur;
}
Evaluation des
expressions arithmétiques
public static void main(String args[]) {
Element[] exp = new Element[args.length];
for (int i = 0; i < args.length; ++i) {
String s = args[i];
if (s.equals ("+") || s.equals ("*")) exp[i] = new Element(true, 0,
s.charAt(0));
else
exp[i] = new Element(false,
Integer.parseInt(s), ' ');
}
System.out.println(evaluer(exp));
}