• Aucun résultat trouvé

EVALUATION DES EXPRESSIONS ARITHMETIQUES PREFIXEES 73

Structures de donnees elementaires

3.3. EVALUATION DES EXPRESSIONS ARITHMETIQUES PREFIXEES 73

function Calculer (a: char; x, y: integer): integer;

begin

La procedure d'evaluation consiste a empiler les resultats intermediaires, la pile con-tiendra des operateurs et des nombres, mais jamais deux nombres consecutivement. On examine successivement les entites de l'expression si l'entite est un operateur ou si c'est un nombre et que le sommet de la pile est un operateur, alors on empile cette entite.

En revanche, si c'est un nombre et qu'en sommet de pile il y a aussi un nombre, on fait agir l'operateur qui precede le sommet de pile sur les deux nombres et on repete l'operation sur le resultat trouve.

Figure 3.3 : Pile d'evaluation des expressions

procedure Inserer (var x: Element; var p: Pile);

var y,z: Element;

begin

if Pvide(p) or (x.nature = Symbole) then Pajouter (x, p)

else begin

y := Pvaleur (p);

if y.nature = Symbole then Pajouter (x, p)

x.valeur := Calculer (z.valsymb, x.valeur, y.valeur);

Inserer (x, p);

end;

end;

end;

function Evaluer (x: Expression; l: integer): integer;

var i: integer;

p: Pile;

y: Element;

begin

FairePvide(p);

for i := 1 to l do

if (x[i].nature = Nombre) or (* Supression des parentheses *)

(x[i].valsymb = '+') or (* ouvrantes et fermantes *)

(x[i].valsymb = '*') then Inserer (x[i],p);

y := Pvaleur (p);

Evaluer := y.valeur;

end;

3.4 Files

Les les sont utilisees en programmation pour gerer des objets qui sont en attente d'un traitement ulterieur, par exemple des processus en attente d'une ressource du systeme, des sommets d'un graphe, des nombres entiers en cours d'examen de certaines de leur proprietes, etc ::: Dans une le les elements sont systematiquement ajoutes en queue et supprimes en t^ete, la valeur d'une le est par convention celle de l'element de t^ete.

En anglais, on parle de strategie FIFOFirst In First Out, par opposition a la strategie LIFO Last In First Out des piles. Sur les les, on denit a nouveau les operations vide,ajouter,valeur,supprimersur les les comme sur les piles. Cette fois, les relations satisfaites sont les suivantes (ou F0 denote la le vide).

Si F 6=F0

supprimer(ajouter(x;F)) =ajouter(x;supprimer(F)) valeur(ajouter(x;F)) =valeur(F)

Pour toute leF

vide(ajouter(x;F)) =faux Pour la le F0

supprimer(ajouter(x;F0)) =F0

valeur(ajouter(x;F0)) =x vide(F0) =vrai

Une premiere idee de realisation sous forme de programmes des operations sur les les est empruntee a une technique mise en uvre dans des lieux ou des clientsfont la queue pour ^etre servis, il s'agit par exemple de certains guichets de reservation dans les gares, de bureaux de certaines administrations, ou des etals de certains supermarches.

Chaque client qui se presente obtient un numero et les clients sont ensuite appeles par les serveurs du guichet en fonction croissante de leur numero d'arrivee. Pour gerer ce systeme deux nombres doivent ^etre connus par les gestionnaires: le numero obtenu par le dernier client arrive et le numero du dernier client servi. On note ces deux nombres par n etdebutrespectivement et on gere le systeme de la facon suivante

la le d'attente est vide si et seulement si debut=n,

lorsqu'un nouveau client arrive on incrementenet on donne ce numero au client,

3.4. FILES 75

lorsque le serveur est libre et peut servir un autre client, si la le n'est pas vide, il incremente debutet appelle le possesseur de ce numero.

Dans la suite, on a represente toutes ces operations en Pascal en optimisant la place prise par la le en utilisant la technique suivante: on reattribue le numero 1 a un nouveau client lorsque l'on atteint un certain seuil pour la valeur den. On dit qu'on a un tableau circulaire. Une verication systematique du fait que la le n'est pas pleine doit alors ^etre eectuee a chaque ajout.

const MaxF = 100;

type Intervalle = 1..MaxF;

Fil = record (* fileest un mot reserve *)

fin, debut: Intervalle;

contenu: array[Intervalle] of Element;

end;

procedure FaireFvide (var f:Fil);

begin

f.debut := 0;

f.fin := 0;

end;

function Successeur (x: Intervalle): Intervalle;

begin

if x = MaxF then Successeur := 1 else

Successeur := x+1;

end;

function Fvide (var f: Fil): boolean;

begin

Fvide := f.fin = f.debut;

end;

function Fpleine (var f: Fil): boolean;

begin

Fpleine := f.debut = Successeur (f.fin);

end;

function Fvaleur (var f: Fil): Element;

var i: Intervalle;

begin

i := Successeur (f.debut);

Fvaleur := f.contenu[i];

end;

procedure Fajouter (x: Element; var f: Fil);

begin

f.fin := Successeur (f.fin);

f.contenu[f.fin] := x;

end;

procedure Fsupprimer (var f: Fil);

begin

12 31 11 22 91 3 13 53 23 8

debut n

La le contient les nombresf13;53;23g

12 31 11 22 91 3 13 53 23 27

debut n

Ajout de l'element 27

12 31 11 22 91 3 13 53 23 27

debut n

Suppressions successives de deux elements

37 31 11 22 91 3 13 53 23 27

debut

n Ajout de l'element 37

12 31 11 22 91 3 13 53 23 27

debut

n File vide apres 2 suppressions

Figure 3.4 : File geree par un tableau circulaire

f.debut := Successeur (f.debut);

end;

Pour ne pas alourdir les programmes ci dessus, nous n'avons pas ajoute des tests veri-ant si la le fn'est pas vide lorsqu'on supprime un element et si elle n'est pas pleine lorsqu'on en ajoute un. Il est par contre vivement conseille de le faire dans un pro-gramme d'utilisation courante. Cette gestion des les en tableau est souvent appelee tampon circulaire.

Une autre facon de gerer des les consiste a utiliser des listes cha^nees gardees (voir page 68) dans lesquelles on conna^t a la fois l'adresse du premier et du dernier element.

Cela donne les operations suivantes:

type

Liste = ^Cellule;

Cellule = record contenu: Element;

suivant: Liste;

end;

Fil = record debut: Liste;

fin: Liste;

end;

procedure FaireFvide(var f: Fil);

begin

3.4. FILES 77

e1 e2 en n0

debut n

Figure 3.5 : File d'attente implementee par une liste

New(f.debut);

f.fin := f.debut;

end;

function Successeur (a: Liste): Liste;

begin

Successeur := a^.suivant;

end;

function Fvide (f: Fil): boolean;

begin

Fvide := f.fin = f.debut;

end;

function Fvaleur (f: Fil): Element;

var b: Liste;

begin

b := Successeur (f.debut);

Fvaleur := b^.contenu;

end;

procedure Fajouter (x: Element; var f: Fil);

var b: Liste;

begin new (b);

b^.contenu := x;

b^.suivant := nil;

f.fin^.suivant := b;

f.fin := b;

end;

procedure Fsupprimer (var f: Fil);

var b: Liste;

begin

if not Fvide(f) then begin

b := f.debut;

f.debut := Successeur (f.debut);

dispose (b) end

end;

Nous avons deux realisations possibles des les avec des tableaux ou des listes cha^nees. L'ecriture de programmes consiste a faire de tels choix pour representer les

e1 e2 e3 e4

a Tail(a)

Figure 3.6 : Queue d'une liste

structures de donnees. L'ensemble des fonctions sur les les peut ^etre indistinctement un module manipulant des tableaux ou un module manipulant des listes. L'utilisation des les se fait uniquement a travers les fonctions vide, ajouter, valeur, supprimer. C'est donc l'interfacedes les qui importe dans de plus gros programmes, et non leurs realisations. Les notions d'interface et de modules seront developpees plus tard.

Documents relatifs