Vous êtes sur la page 1sur 14

Solution

Objectifs
1. apprendre aux étudiants (et à nous-même), qu’avant de s’attaquer à l’écriture du code des
fonctions ou des programmes (en algorithmique, JAVA, ou autre), de réfléchir à la
spécification des opérations correspondantes, en termes de leur profil, préconditions et
propriétés (axiomes) (TAD).
2. Ainsi, même si la question posée concerne l’écriture d’une fonction, il faut tjs commencer par
l’opération associée ; donc : profil, préconditions et axiomes ensuite la fonction demandée.
3. Rappeler à chaque fois que :
a. l’entête d’une fonction demandée est obtenue à partir du profil de l’opération que la
fonction est censée implémenter ;
b. Et quesoncorpsest déterminé soit, à partir des propriétés (axiomes) de l’opération si
possible (meilleure solution favorisant la réutilisation de la fonction), soit un code basé
sur la représentation interne (type) choisi.

4. A l’écriture des propriétés des opérations, commencez par les axiomes avec les constructeurs
en partie gauche, puis chercher tjs des axiomes (réutilisables directement à
l’implémentation : c.a.d ds les fonctions). Ces axiomes ne comportent pas de constructeurs en
partie gauche, mais des variables des sortes définies (exemple pr une liste :
L au lieu de insérer (L,e,i), pr une pile : P au lieu de empiler(P,e)…).

5. Pensez surtout aux solutions génériques donc réutilisables et n’oubliez pas l’efficacité
(complexité réduite) de vos solutions. Le choix des structures de données à un effet sur
l’efficacité ; vous aurez à choisir la structure la plus adaptée.

Ces objectifs restent valables avec les prochaines série de TD.

Exercice 01
Profil
surface: cercle  réel
_ _ appartient à _: réel, réel  booléen
Axiomes
surface(d)  rayon(d) * rayon(d) * 3.14

x y appartient à C Si ([x-centre(C)-x]2-[y-centre(C)-y]2)1/2 =rayon(C) alors vrai Sinon faux

Internes constructeurs: nouveau-cercle


Observateurs: x-centre, y-centre, rayon
TAD CERCLE Variables :
Utilise REEL /BOOLEEN u,v,r : Réels ; d : cercle, C :cercle
Sorte cercle Préconditions :
Opérations : Pré(nouveau-cercle(u,v,r)) définie ssi r>0
nouveau-cercle : réel, réel, réel  cercle Axiomes :
Rayon(nouveau -cercle(u, v, r))  r
x- centre : cercle réel
x-centre(nouveau -cercle(u, v, r))  u
y-centre : cercle  réel
y-centre(nouveau -cercle(u, v, r))  v
rayon : cercle  réel
Exercice 02
1/

TAD ENSEMBLE
Utilise ELEMENT BOOLEEN
Sorte ensemble
Opérations
:  ensemble
ajouter : élément, ensemble  ensemble
supprimer : élément ensemble ensemble
appartient : élément ensemble  booléen
choisir : ensemble  élément
Préconditions
pré(choisir (E)) est définie ssi E  
pré(supprimer (e, E)) est définie ssi appartient(e,E )

Variables
E : ensemble e’,e : éléments
Axiomes
supprimer(e, Ajouter(e’,E)) ≡ si e=e’ alors E sinon Ajouter(e’, supprimer(e,E))
appartient(e, ) ≡ faux
appartient(e, ajouter(e’,E)) ≡ si e=e’ alors vrai sinon appartient(e,E)

2/

, ajouter: opérations internes constructeurs

supprimer: opérations internes non constructeurs

Choisir , appartient: observateurs

3/

Donnée Correcte Sens selon les axiomes


syntaxiquement

Ajouter(a, ajouter(b, ajouter(a, ))) Oui Ajouter(a, ajouter(b, ajouter(a,


)))

Appartient(x, ajouter(b, ajouter(a, ))) Oui Faux (voir l’explication en


dessous)

supprimer(2, ajouter(4, ajouter(5, Oui ajouter(4, ajouter(5, ajouter(4,


ajouter(2, ajouter(4, ))))) )))

Sens selon les axiomes

b. Pour connaitre de sens de cette axiome « Appartient(x, ajouter(b, ajouter(a, ))) » on va utiliser les
axiomes de l’opération Appartient :
appartient(e, ) ≡ faux ……….(1)
appartient(e, ajouter(e’,E)) ≡ si e=e’ alors vrai sinon appartient(e,E) ……….(2)

Etape 1 : e=x, e’=b et E= ajouter(a, ) en appliquant le sinon de (2):

Appartient(x, ajouter(b, ajouter(a, ))) = appartient(x, ajouter(a, ))

Etape 2 : e=x, e’=a et E= en appliquant le sinon de (2):

appartient(x, ajouter(a, ))= appartient(x, )

Etape 3 : e=x et E= en appliquant l’axiome (1) :

appartient(x, )=Faux

c. Pour connaitre de sens de cette axiome « supprimer(2, ajouter(4, ajouter(5, ajouter(2, ajouter(4,
))))) » on va utiliser l’axiome de l’opération supprimer.

supprimer(e, Ajouter(e’,E)) ≡ si e=e’ alors E sinon Ajouter(e’, supprimer(e,E))…………….(3)

Etape 1 : e=2, e’=4 et E=ajouter(5, ajouter(2, ajouter(4, ))) en appliquant le sinon de (3):

supprimer(2, ajouter(4, ajouter(5, ajouter(2, ajouter(4, )))))= ajouter(4, supprimer(2, ajouter(5,


ajouter(2, ajouter(4, ))))

Etape 2 : e=2, e’=5 et E=ajouter(2, ajouter(4, )) en appliquant le sinon de (3):

ajouter(4, supprimer(2, ajouter(5, ajouter(2, ajouter(4, ))))= ajouter(4, ajouter(5, supprimer(2,


ajouter(2, ajouter(4, )))

Etape 3 : e=2, e’=2 et E= ajouter(4, ) en appliquant le si de (3):

ajouter(4, ajouter(5, supprimer(2, ajouter(2, ajouter(4, )))= ajouter(4, ajouter(5, ajouter(4, )))

4/
Profil:
cardinalité: ensemble  entier
Axiomes:
cardinalité()  0
cardinalité(ajouter(e,E))  si appartient(e,E) alors cardinalité(E )
sinon 1+cardinalité(E )
Variables e: élément, E: ensemble

Exercice 03
1. Par réutilisation du type abstrait de données LISTE étudié en cours, le rôle de
l’opération : Chercher-Liste (selon son profile et ses axiomes) est de chercher un
élément e dans une liste avec un résultat booléen (vrai: l’élément existe, faux sinon),
car nous avons la sémantique suivante :
chercher-liste(e, liste-vide)  faux

chercher-liste(e, insérer(L,e', i))  si e==e' alors vrai sinon chercher-liste(e, L)

2. 2. chercher-liste avec en résultat une position

Profil:
chercher-liste: élément, liste entier
préconditions :
aucune
Axiomes:
Rq : Axiome avec les constructeurs en arguments, puis nous cherchons d’autres
axiomes sans les constructeurs en arguments (axiomes réutilisables à
l’implémentation, c.a.d le passage aux fonctions, ici en pseudocode)

chercher-liste(e, liste-vide)  -1
chercher-liste(e, insérer(L,e', longueur (L))  si e==e' alors longueur (L)
sinon chercher-liste(e, L)

Avec des axiomes réutilisables (sans les constructeurs en arguments), et comme nous avons
besoin de la position de l’élément e à chercher, nous allons avoir deux versions de l’axiome (c’est
un seul axiome en sens, mais avec la position, nous aurons 2 positions à considérer selon que la
liste sera implémentée de façon chainée ou contiguë. Ici : L une adresse de début ( un pointeur)
ou longueur (L), en entier)

chercher-liste(e, liste-vide)  -1
chercher-liste(e, L)  si e= Acces(L,L) alors L
sinon chercher-liste(e, supprimer(L,L))

Rq : Les opérations supprimer(L,L) et supprimer(L,1) ou


supprimer(L, Longueur(L)) n’altèrent pas la liste. C.a.d ne détruisent pas les
éléments de la liste. Elle le font localemtent (la ou il le faut) et grâce au passage par
donnée, au retour de chq fonction la liste avec son état précédent est récupérée.

chercher-liste(e, liste-vide)  -1
chercher-liste(e, L)  si e= Acces(L,Longueur(L)) alors Longueur(L)
sinon chercher-liste(e, supprimer(L, Longueur(L)))

3. Avec l’implémentation contigüe voici le corps de la fonction chercher-liste :

Fonction chercher-liste (D e: élément , D L: liste): entier


Déclaration
Fonction Liste-vide ( ) : Liste
Début
// L’implémentation contigüe de la fonction (voir le cours)
Fin
Fonction Longueur (L :liste) :entier
Début
// L’implémentation contigüe de la fonction (voir le cours)
Fin
Fonction Accès (L :liste, pos :entier) : élément
Début
// L’implémentation contigüe de la fonction (voir le cours)
Fin
Fonction supprimer (L :liste, pos :entier) :Liste
Début
// L’implémentation contigüe de la fonction (voir le cours)
Fin

Début
Si (L= Liste-vide ( )) alors retourner -1
Sinon
Si e=Accès (L, Longueur(L)) alors retourner Longueur(L)
Sinon retourner (chercher-liste(e, supprimer(L, Longueur(L)))
Finsi
Finsi
Fin

Exercice 04

1.a Profiles des opérations :


Ajouter-fin: liste, élément  liste
Queue : liste élément
Somme : liste  entier
Egale : liste, liste Booleen
Inverse: liste liste
Variables: L, L1,L2: liste

Précondition

Queue (L) définie ssiL≠liste-vide


Somme(L) définie ssiL≠liste-vide
Egale (L1, L2) définie ssi Longueur(L1)== Longueur(L2)

2.b. Avec L'implémentation Chainée de la liste, développez des fonctions implémentant les
opérations: Ajouter-fin (L, e) et Queue ( L). Alors il faut passer par les Axiomes pour plus de
généricité des fonctions à développer.

Axiomes
Ajouter-fin (L, e) insérer(L, Null, e)
Queue (L)Si supprimer(L,L)= = liste-vide alors accès(L,L)
Sinon Queue(supprimer(L,L)
Ou bien par utilisation de l’opération Suivant (L), nous aurons :
Queue (L)si Suivant (L) == liste-vide alors accès (L,L)
Sinon queue(Suivant (L))

2.b. Implémentation Chainée de la liste :


Donc utilisez le type liste= Pointeur de cellule et les fonctions de base associées aux
opérations TAD LISTE (voir le 1.2.2. chap3-partie 2: Implémentation chainée
Déclarations
Type:
Liste =pointeur de cellule
cellule= enregistrement
Info: élément
Suiv : pointeur de cellule
Fin
Position: Pointeur de cellule ou liste
var
L:Liste,

Fonction Liste-vide():liste
Début/* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Retourner NULL
fin

Fonction Insérer(D L: liste, D p : Position , D e: élément): liste


Début /* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Déclaration
Nouv, Pt : liste
Début
Nouv= allouer(cellule)
Nouv.Info=e
Nouv.Suiv=p/*insertion avant l’elem de position p
Sip= L /* insertion au début */
AlorsL Nouv
Sinondebut
PtL
Tanque Pt.suiv  p faire
PtPt.suiv
Fintq
Pt.suiv Nouv /* insertion à la fin ( p= null) et à l’interieur
fin
Fsi
retourner(L)
Fin

Fonction Supprimer(D L: liste, D p:Position): liste


Début/* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Déclaration
Pt1, Pt2: liste
Début
Si p=L alors retourner (L.suiv)/* suppresion au début de complexité:0(1)
Sinon
Pt1L
Pt2L.suiv
tanque Pt2  p faire
Pt1Pt1.suiv
Pt2Pt2.suiv
Fintq
Pt1.suivPt2.suiv /* ou bien Pt1.suivP.suiv
retourner(L)
Fsi
Fin

Fonction accès(D L: liste, D p : Position): élément


Début /* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Retourner(P.info)
fin

Fonction Ajouter-fin(D L: liste, D e : élément) : liste


Déclarations
/* déclarez toutes les fonctions utilisées (entête et corps),
ici c’est insérer (L,p,e);nous l’avons déclarée au début
Début/* nous réutilisons l’axiome
Retourner(insérer(L,Null,e) ) /* avec P= Null, l’insertion se fait à la fin
Fin
Fonction Queue (D L: liste) : élément
Déclarations
/* déclarez toutes les fonctions utilisées, ici c’est : liste-vide ( ),accès(L,L)
et supprimer(L,L) (entête et corps);nous les avons déclarées au début
Debut/* nous réutilisons l’axiome
Si supprimer(L,L) = = liste-vide ( )
Alors Retourner (accès(L,L))
Sinon Retourner (Queue(supprimer(L,L))
Fin

3- Ecrivez un algorithme, basé sur les fonctions précédentes, qui permet de :


 Créer une liste L1 contenant N entiers
 Afficher l’élément en queue de L1.

Remarque : Nous allons écrire l’algo complet en instanciant Elément dans le TAD
LISTE par Entier

Algorithme Exercice3 -implémentation chainée-liste


Déclarations
Type:
Liste =pointeur de cellule
cellule= enregistrement
Info: élément
Suiv : pointeur de cellule
Fin
Position: Pointeur de cellule ou liste
var
L:Liste,
N, NB, i : entier,

Fonction Liste-vide():liste
Début /* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Retourner NULL
fin

Fonction Insérer(D L: liste, D p : Position , D e: élément): liste


Début /* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Déclaration
Nouv, Pt : liste
Début
Nouv= allouer(cellule)
Nouv.Info=e
Nouv.Suiv=p /*insertion avant l’elem de position p
Sip= L /* insertion au début */
AlorsL Nouv
Sinondebut
PtL
Tanque Pt.suiv  p faire
PtPt.suiv
Fintq
Pt.suiv Nouv /* insertion à la fin ( p= null) et à l’interieur
fin
Fsi
retourner(L)
Fin

Fonction Supprimer(D L: liste, D p: Position): liste


Début /* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Déclaration
Pt1, Pt2: liste
Début
Si p=L alors retourner (L.suiv) /* suppresion au début de complexité: 0(1)
Sinon
Pt1L
Pt2L.suiv
tanque Pt2  p faire
Pt1Pt1.suiv
Pt2Pt2.suiv
Fintq
Pt1.suivPt2.suiv /* ou bien Pt1.suivP.suiv
retourner(L)
Fsi
Fin
Fonction accès(D L: liste, D p : Position): élément
Début /* voir le 1.2.2. chap3-partie 2 : Implémentation chainée
Retourner(P.info)
fin

Fonction Ajouter-fin(D L: liste, D e : élément) : liste


Début
Retourner (insérer(L,Null,e) ) /* avec P= Null, l’insertion se fait à la fin
Fin

Fonction Queue (D L: liste) : élément


Debut
Sisupprimer(L,L) = = liste-vide ( )
alorsRetourner(accès(L,L))
SinonRetourner(Queue(supprimer(L,L))
Fin

Début /* Algorithme Exercice3 -implémentation chainée-liste


1. Lire (N) /* N= nbre d’elements
2. L=Liste-vide()
3. Pour i=1 à N faire
4. Lire(NB)
/* L=insérer (L, L, NB) est une fonction plus
5. L=Ajouter-fin (L, NB)
optimale que Ajouter-fin (L, NB), pourquoi ???
Finpour
6. Si est-vide (L)= faux/* précondition de la fonc
7. Alors Ecrire ("l’élément en queue de L est:", Queue (L))
finsi
Fin
Remarque le mm algo avec une implémentation contiguë de la liste est plus optimal que
le précédent, pourquoi ???
( car Ajouter-fin (L, NB) insérer (L, Longueur(L)+1, NB) est plus rapide que Ajouter-
fin (L, NB) et pr la fonction Queue (L) ???????? avec implémentation contiguë de la
liste, que pensez Vous ????????? ( c simple, écrivez l’axiome et vous allez voir la
différence entre les 2 implémentations.
Exercice 05:
Solution exo 5
1. Profile:
Produit-liste : liste, liste  liste
Variables L1, L2: liste
Axiomes:
Produit-liste (liste-vide, liste-vide) ≡ liste-vide

Produit-liste (L1, L2) ≡ insérer (Produit-liste (supprimer (L1,1),


supprimer(L2,1)), 1, accès(L1,1)*accès(L2,1))

2.Fonction récursive

Fonction Produit-liste (D L1:liste, D L2:liste): liste


Déclarations /juste les déclarations des entêtes des fonctions de base
utilisées (sans leur corps car la fonction Produit-liste (…)
est indépendante des implémentations (elle est générique)

Fonction liste-vide( ): liste


Fonction est-vide(D L:liste ): Booléen
Fonction insérer(D L:liste, D i: entier, D e: réel): liste
Fonction supprimer(D L:liste, D i: entier): liste
Fonction accès (D L:liste, D i: entier): réel
Début
Si est-vide(L1) et est-vide(L2 )
Alors retourner liste-vide( )
Sinon retourner(insérer(Produit-liste (supprimer(L1,1),
supprimer(L2,1)), 1, accès(L1,1)*accès(L2,1)))
finsi
Fin

Algorithme EXO-03 /*générique et indépendant


des implémentations des listes)
Déclarations
L1, L2, LPROD :liste
R1, R2:réel ; I: entier
Fonction liste-vide( ): liste
Fonction est-vide(D L:liste ): Booléen
Fonction insérer (D L:liste, D i: entier, D e: réel): liste
Fonction accès (D L:liste, D i:entier): réel
Fonction supprimer (D L:liste, D i:entier): liste
Fonction Produit-liste (D L1, L2:liste): liste

Début
Si est-vide(L1) et est-vide(L2 )
Alors retourner liste-vide( )
Sinon retourner(insérer(Produit-liste (supprimer(L1,1),
supprimer(L2,1)), 1, accès(L1,1)*accès(L2,1)))
finsi
Fin

Début /* Algorithme EXO-03


L1L2LPROD liste-vide ( )
Pour I = 1 à 500 faire
lire( R1, R2)
L1 insérer(L1, 1, R1)
L2 insérer(L2, 1, R2)
finpour
LPRODProduit-liste (L1, L2)
Tantque est-vide (LPROD) ≠ vrai faire
écrire( accés (LPROD, 1))
LPROD supprimer(LPROD, 1)
fintq
Fin
NB : Cet algo est générique, alors vs pouvez le réutiliser avec l’impl chainée ou contiguë
des listes ( L1, L2 et LPROD). Il suffit de choisir selon votre Pbm, l’une des 2 impls, de
mettre sa déclaration et ajouter les corps des fonctions de base utilisées.

Exercice 06

Par exemple, L1= (15,2,5,3,9,6,10,4,75) et L2= (5,3,9,4,15), différence(L1,L2)=(2,6,10,75)

Profil :

Différence : liste, liste  liste

Axiomes :
Différence (liste-vide,L2) ≡liste-vide
Différence (L1, liste-vide) ≡L1
Différence (L1, L2) ≡ si chercher-list (L2, accès(L1, 1))
alors Différence(supprimer(L1, 1),L2)
sinon insérer (Différence(supprimer(L1,1),L2), 1, accès(L1,1))

NB : le 1 sera ajusté par L pr les fonctions de l’implémentation chainée

Fonction Différence (Donnée L1,L2 : liste): liste


/* declaration de toutes les fonctions utilissées avec l’entête uniquement car
l’exo6 n’a pas précisé l’impl de la liste. Alors la Fonction Différence est générique
Fonction est-vide (Donnée L: liste): booleen
Fonction accès(D L L: liste .......
Fonction supprimer ( …… /* juste les entêtes, pas de corps ici, c générique.
Fonction chercher-list (…..
Fonction insérer ( …….

Svp : complétez les entêtes

Debut
si chercher-list (L2, accès(L1, 1))
alors retourner (Différence(supprimer(L1, 1),L2) )
sinon retourner ( insérer (Différence(supprimer(L1,1),L2), 1, accès(L1,1)) )
finsi
Fin

NB : Cette fonction reste inchangée avec les 2 implémentations, le rang 1 d’une liste
restera 1 en contiguë et L en chainée avec l’ajout des corps des fonctions de base
utilisées selon l’implémentation choisie.

Conclusion : La réutilisation, obtenue grâce à la « généricité » des solutions, est l’un des
objectifs du recours au TAD.

Exercice 07
1. Profil :
Maximum : liste  réel
Précondition
Maximum non définie si la liste est vide

Axiome
Maximum(L)= Si est-vide (supprimer(L, 1)) alors accés(L, 1)
sinon Si accés(L, 1) > maximum(supprimer(L, 1))
alors accés(L, 1) sinon maximum(supprimer(L, 1)))
Ou bien de façon plus concise
Maximum(L)= Si est-vide (supprimer(L, 1)) ou si accés(L, 1) > maximum(supprimer(L, 1))
alors accés(L, 1) sinon maximum(supprimer(L, 1)))

NB : pr la fonction en chainée, ns adaptons le 1 par L et nous donnerons les entêtes et


corps des fonctions de bases utilisées, comme suit :

Fonction Maximum(Donnée L : liste): réel


Déclarations
Fonction liste-vide ( ): liste
Debut /* il faut ajouter le corps de l’impl chainée ici fin
Fonction accés ( D L: liste, donnée p:position): réel
Debut /* il faut ajouter le corps de l’impl chainée ici fin
Fonction supprimer( D L: liste, Donnée p: position): liste
Debut /* il faut ajouter le corps de l’impl chainée ici fin

Début
Si est-vide (supprimer(L, L)) ou accés(L,L) > maximum(supprimer(L,L))
Alors Retourner(accés(L,L))
Sinon retourner(maximum(supprimer(L,L)))
Fsi
Fin

Vous aimerez peut-être aussi