On s'intéresse sur cette page au type abstrait de données « Pile » que l'on représente à l'aide d'une classe Pile dont on fournit le code ci-dessous.
La classe Pile
classPile:def__init__(self):"""Initialise une pile vide"""self.valeurs=[]defest_vide(self):"""Renvoie un booléen : la pile est-elle vide ?"""returnlen(self.valeurs)==0defempile(self,element):"""Empile un élément au sommet de la pile"""self.valeurs.append(element)defdepile(self):""" Dépile un élément au sommet et le renvoie. Provoque une erreur si la pile est vide. """ifself.est_vide():raiseValueError("Erreur, pile vide")else:returnself.valeurs.pop()def__repr__(self):"""Affiche la pile, en indiquant le sommet"""returnf"| {' | '.join([str(x)forxinself.valeurs])} | <- sommet"def__eq__(self,autre):""" Détermine si cette pile et l'autre sont égales (mêmes valeurs, dans le même ordre) """returnself.valeurs==autre.valeurs
Cette classe possède deux méthodes spéciale __repr__ et __eq__ qui permettent :
d'afficher le contenu de la pile (__repr__) ;
de tester l'égalité entre la pile étudiée et une autre pile passée en paramètre (__eq__).
Les lignes ci-dessous présentent un exemple d'utilisation. On prendra soin, dans les différents exercices, de n'utiliser que les méthodes présentées ci-dessous.
Utilisation
>>> p=Pile()# création d'une pile vide>>> p.est_vide()# la pile est-elle vide ? -> OuiTrue>>> p.empile(0)# empile 0 dans la pile>>> p.est_vide()# la pile est-elle vide ? -> NonFalse>>> p.empile(1)# empile 0 dans la pile>>> p# affichage du contenu de p| 0 | 1 | <- sommet>>> p.depile()# dépile une valeur1>>> p| 0 | <- sommet>>> q=Pile()>>> q.empile(1)>>> q| 1 | <- sommet>>> p==q# les piles p et q sont-elles égales ? -> NonFalse
Les exercices ci-dessous sont indépendants. Ils sont néanmoins présentés dans un certain ordre permettant d'aborder successivement plusieurs techniques.
Jouons le jeu !
Ces exercices visent à utiliser certaines techniques classiques liées aux piles. Il est donc demandé de les traiter en se limitant à l'utilisation des méthodes la classe Pile.
Il est en particulier interdit d'accéder directement à l'attribut valeurs.
Accéder ou modifier cet attribut fera échouer les tests secrets.
Calculer la taille d'une pile
Écrire la fonction taille qui prend en paramètre une pile et renvoie son nombre d'éléments.
A l'issue du traitement, la pile doit avoir retrouvé son état initial.
Écrire la fonction renverse_k qui prend en paramètre une pile ainsi qu'un entier k et renverse l'ordre des k premiers éléments de la pile. Les autres éléments ne sont pas modifiés.
La transformation se fait en place : on modifie directement sur la pile et il est donc inutile de la renvoyer.
On garantit que la pile compte au moins k éléments.
>>> p=Pile()>>> p.empile("a")>>> p.empile("b")>>> p.empile("c")>>> p.empile("d")>>> p.empile("e")>>> p| a | b | c | d | e | <- sommet>>> renverse_k(p,4)>>> p| a | e | d | c | b | <- sommet
Aide
On pourra utiliser deux piles annexes.
###(Dés-)Active le code après la ligne # Tests (insensible à la casse) (Ctrl+I)
Entrer ou sortir du mode "deux colonnes" (Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran" (Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
On considère p et q deux piles contenant le même nombre d'éléments.
On appelle « fusion de p et q » la pile obtenue en empilant alternativement les valeurs dépilées de p puis q.
Écrire la fonction fusion_simple qui prend en paramètre deux piles de même taille et renvoie la pile résultante.
Les piles p et q peuvent être modifiées lors du traitement.
>>> p=Pile()>>> p.empile("c")>>> p.empile("a")>>> p| c | a | <- sommet>>> q=Pile()>>> q.empile("d")>>> q.empile("b")| d | b | <- sommet>>> fusion_simple(p,q)| a | b | c | d | <- sommet
###(Dés-)Active le code après la ligne # Tests (insensible à la casse) (Ctrl+I)
Entrer ou sortir du mode "deux colonnes" (Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran" (Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
On considère p et q deux piles dont on ignore le nombre d'éléments.
On appelle « fusion de p et q » la pile obtenue en empilant alternativement les valeurs dépilées de p puis q.
Les piles n'ayant pas nécessairement le même nombre d'éléments, il est possible lors de la fusion que l'une d'elles soit vide avant l'autre.
Dans ce cas, on terminera la fusion en vidant l'autre pile dans la pile résultante.
Écrire la fonction fusion qui prend en paramètre deux piles de tailles inconnues et renvoie la pile résultante.
Les piles p et q peuvent être modifiées lors du traitement.
>>> p=Pile()>>> p.empile("e")>>> p.empile("c")>>> p.empile("a")>>> p| e | c | a | <- sommet>>> q=Pile()>>> q.empile("d")>>> q.empile("b")| d | b | <- sommet>>> fusion_simple(p,q)| a | b | c | d | e | <- sommet
Aide
On pourra organiser le code en trois temps :
les deux piles sont non-vides ;
la pile p est non-vide ;
la pile q est non-vide.
###(Dés-)Active le code après la ligne # Tests (insensible à la casse) (Ctrl+I)
Entrer ou sortir du mode "deux colonnes" (Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran" (Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)