Exercices
Les interfaces des structures de données abstraites Pile
et File
sont rappelées ci-dessous.
- Structure de données abstraite:
Pile
creer_pile_vide: () → Pile
:creer_pile_vide()
renvoie une pile videest_vide:Pile → Booléen
:est_vide(pile)
renvoieTrue
si pile est vide,False
sinonempiler: Pile, Élément → ∅
:empiler(pile,element)
ajouteelement
à la pilepile
depiler: Pile → Élément
:depiler(pile)
renvoie l’élément au sommet de la pile en le retirant de la pile
- Structure de données abstraite:
File
creer_file_vide: () → File
:creer_file_vide()
renvoie une file videest_vide:File → Booléen
:est_vide(file)
renvoieTrue
si file est vide,False
sinonenfiler: File, Élément → ∅
:enfiler(file,element)
ajouteelement
à la filefile
defiler: File → Élément
:defiler(file)
renvoie l’élément au sommet de la file en le retirant de la file
On répondra aux questions en utilisant uniquement les fonctions données dans l'interface des type Pile
et File
. On dispose de plus de deux fonctions d'affichage affiche_pile
et affiche_pile
qui étant donné une pile p
(resp. une file f
) en proposent un affichage de la manière suivante :
1 2 3 4 5 6 7 8 |
|
| 2 | -> sommet
| 1 |
-----
---
enfilement -> 2 1 -> défilement
---
Manipulations¶
- Soit une pile
p
une pile composée des éléments suivants :12
,14
,8
,7
,19
et22
(le prochain élément à être dépilé est22
).- Écrire le code python permettant d'instancier une variable
p
correspondant à la pile de l'énoncé. - Que renvoie
depiler(p)
? De quels éléments est maintenant composéep
? - On exécute
empiler(p, 42)
. De quels éléments est maintenant composéep
? - Écrire une fonction
sommet
qui prend en argument une pilep
et qui en renvoie l'élément placé au sommet. À la fin de l'exécution, la pilep
doit être dans le même état qu'initialement. - Après avoir appliqué
depiler(p)
une fois, quelle est la taille de la pile ? - Si on applique
depiler(p)
5 fois de suite, que renvoieest_pile_vide(p)
?
- Écrire le code python permettant d'instancier une variable
- Soit une file
f
composée des éléments suivants : 12, 14, 8, 7, 19 et 22 (le prochain élément à être défilé est22
).- Écrire le code python permettant d'instancier une variable
f
correspondant à la file de l'énoncé. - On effectue
enfiler(f, 42)
. De quels éléments est maintenant composéef
? - Que renvoie
defiler(f)
? De quels éléments est maintenant composéef
? - Écrire une fonction
tete
qui prend en argument une filef
et qui en renvoie l'élément placé en première position de la file. À la fin de l'exécution, la filef
doit être dans le même état qu'initialement. - Si on applique
defiler(f)
5 fois de suite, que renvoieest_file_vide(f)
?
- Écrire le code python permettant d'instancier une variable
Algorithmes sur les piles¶
Les éléments constituant les piles de cet exercice sont des entiers. On ne se souciera pas de restaurer l'état de la pile après exécution des fonctions demandées.
-
Écrire une fonction
tamis
qui étant donné une pilep
renvoie deux pilesp_pair
etp_impair
contenant respectivement les éléments pairs et impairs de la pilep
.1 2 3
def tamis(p): """ Pile -> Pile, Pile """ pass
-
Écrire une fonction
maximum
qui étant donné une pilep
non vide renvoie le plus grand élément de la pile.1 2 3
def maximum(p): """ Pile -> int """ pass
-
Écrire une fonction python
retourne
inversant l'ordre des éléments présents dans la pilep
.1 2 3
def retourne(p): """ Pile -> None""" pass
Expression bien parenthésée¶
On dit qu'une chaîne de caractères constituée de parenthèses ouvrantes (
et fermantes )
est bien parenthésée lorsque chaque parenthèse ouvrante est associée à une unique fermante, et réciproquement. Par exemple la chaîne de caractères ()()()
est correctement parenthésée tandis que la chaîne de caractères (()((
ne l’est pas.
-
- La chaîne de caractères
(())()
est-elle correctement parenthésée ? - Donner toutes les chaînes de caractères de taille 6 correctement parenthésées (il y en a cinq).
- La chaîne de caractères
-
-
Écrire une fonction
est_bien_parenthesee
qui étant donné une chaîne de caractèrechaine
renvoieTrue
si et seulement sichaine
est une expression bien parenthésée. On utilisera pour cela l'algorithme suivant :- on initialise une pile vide
p
- pour chaque symbole de la chaîne de caractères :
- si le symbole est une parenthèse ouvrante, on l'empile dans
p
- si le symbole est une parenthèse fermante, on dépile
p
.
- si le symbole est une parenthèse ouvrante, on l'empile dans
- l'expression est correctement parenthésée si et seulement si l'algorithme se termine correctement et la pile finale est vide.
1 2 3
def est_bien_parenthesee(chaine): """ str -> bool """ pass
1 2
print(est_bien_parenthesee("()")) print(est_bien_parenthesee("("))
True False
- on initialise une pile vide
-
Appliquer votre algorithme aux deux expressions données en exemple dans l'énoncé. Détailler les états successsifs de la pile utilisée.
-
-
On applique un algorithme dit "générer et filtrer" afin d'obtenir la liste de toutes les expressions correctement parenthésées. Pour cela, on commence par générer la liste de toutes les expressions de taille
n
fixée constituées uniquement de symboles(
et)
. Puis, on filtre les résultats obtenus en ne gardant que les expressions correctement parenthésées.-
Combien y a-t-il d'expressions de taille 4, constituées uniquement de symboles
(
et)
? -
Soit \(n\in \mathbb{N}\). Combien y a-t-il d'expressions de taille \(n\), constituées uniquement de symboles
(
et)
? -
Pour tout nombre \(i \in \mathbb{N}\) s'écrivant sur
n
bits, on associe la chaîne de caractère dans laquelle tous les 0 de l'écriture binaire de \(i\) ont été remplacés par'('
et tous les 1 par')'
.On admet que la fonction
int2strbin
prend en entrée deux nombres entieri
etn
et renvoie la chaîne de caractère correspondant à son écriture en base 2 surn
bits. On pourra l'utiliser sans justification.1
print(int2strbin(5, 6))
000101
Écrire une fonction
expression
qui prend en entrée un entieri
et un entiern
et qui renvoie la chaîne den
caractères constituée uniquement de parenthèses correspondante.1 2 3
def expression(x, n): """ int, int -> str """ pass
1
print(expression(5, 6))
((()()
-
Écrire une fonction
liste_bien_parenthesee
qui prend en argument un entiern
et qui renvoie la liste de toutes les expressions de taillen
correctement parenthésées.On pourra utiliser les fonctions
est_bien_parenthesee
etexpression
écrite précédemment.1 2
print(liste_bien_parenthesee(2)) print(liste_bien_parenthesee(4))
['()'] ['(())', '()()']
-
Notation polonaise inverse¶
L'écriture polonaise inverse des expressions arithmétiques place l'opérateur après ses opérandes. Cette notation ne nécessite aucune parenthèse ni aucune règle de priorité. Ainsi l'expresion polonaise inverse décrite par la chaîne de caractères 1 2 3 * + 4 *
désigne l'expression traditionnellement notée \((1+2 \times 3) \times 4\). La valeur d'une telle expression peut être calculée facilement en utilisant une pile pour stocker les résultats intermédiaires. Pour cela, on observe un à un les éléments qui constituent l'expression et on effectue les actions suivantes :
- si on voit un nombre, on le place sur la pile;
- si on voit un opérateur binaire, on récupère les deux nombres au sommet de la pile, on leur applique l'opérateur, et on replace le résultat sur la pile.
Si l'expression était bien écrite, il y a bien toujours deux nombres sur la pile lorsque l'on voit un opérateur, et à la fin du processus il reste exactement un nombre sur la pile, qui est le résultat.
-
- À quel expression écrite en notation polonaise inverse correspond l'expression traditionnellement notée \(2 + 3\times(4 + 5/6)\) ?
- Quel est le résulat de l'expression qui s'écrit en notation polonaise inverse
3 4 - 12 1 + *
? Détailler les états intermédiaires de la pile de calcul.
-
On représente une expression par une chaîne de caractères. Compléter le code de la fonction
decoupe
qui prend en entrée une chaîne de caractèree
et qui renvoie la file des éléments qui la constituent (dans leur ordre d'occurrence).1 2 3 4 5 6 7 8 9 10 11 12 13
def decoupe(e): f = creer_file_vide() element_en_lecture = '' for c in e: if c in {'+', '-', '/', '*'}: enfiler(..., ...) element_en_lecture = ... elif ... and not element_en_lecture == '': ... ... else: ... return f
1 2 3
e = '3 4 - 12 1 + *' f = decoupe(e) affiche_file(f)
-------------------- enfilement -> "*" "+" 1 12 "-" 4 3 -> défilement --------------------
-
Écrire le code d'une fonction
evalue
qui étant donné une filef
dont les éléments sont des entiers et les chaînes"+"
"-"
"*"
"/"
renvoie le résultat du calcul écrit en notation polonaise inverse correspondant.On renverra la valeur spéciale
None
si le calcul n'est pas écrit correctement.1 2 3
def evalue(f): """ File -> int """ pass
1
print(evalue(f))
13
-
Écrire une fonction
calculatrice_npi
qui étant donné une chaîne de caractèresentree
qui décrit un calcul utilisant la notation polonaise inverse, renvoie le résultat de ce calcul.1 2 3
def calculatrice_npi(entree): """ str -> int """ pass
1
print(calculatrice_npi("1 2 3 * + 4 *"))
28
Tri de pile¶
On souhaite trier les éléments d'une pile A
. On propose pour cela l'algorithme suivant :
- on utilise deux piles
B
etC
, initialement vides ; -
tant que
A
n'est pas vide, on est dans l'un des cas suivants :-
soit la pile
B
est vide ou bien l'élément au sommet deA
est plus petit que l'élément au sommet deB
.Dans ce cas on retire l'élément au sommet de
A
pour l'empiler au sommet deB
. Si la pileC
n'était pas vide, on en dépile les éléments les uns après les autres et on les empile dansB
. -
sinon on dépile l'élément au sommet de
B
et on l'empile dansC
.
-
-
la pile
B
contient les éléments deA
triés (le minimum est au sommet). -
Suivre le déroulé de l'algorithme avec la pile
A = [4, 3, 2, 5, 8, 2, 6, 9, 3]
(le sommet de la pile est 3). - À quel algorithme de tri cela vous fait-il penser ?
- Implémenter cet algorithme en python (vous n'utiliserez que les fonctions de l'interface du type
Pile
).
Type bac I¶
-
On suppose dans cette question que
p
est la pile[8, 5, 2, 4]
(le sommet de la pile est 4).Quel sera le contenu de la pile
q
après exécution du code ci dessous ?1 2 3
q = creer_pile_vide() while not est_pile_vide(p): empiler(q, depiler(p))
-
On appelle hauteur d'une pile le nombre d'élément qui la composent. Écrire une fonction
hauteur_pile
qui prend comme argument une pilep
et en renvoie sa hauteur. Après l'appel de cette fonction, la pilep
doit avoir retrouvé son état d'origine.1 2
print(hauteur_pile(q)) affiche_pile(q)
4 | 8 | -> sommet | 5 | | 2 | | 4 | -----
-
Écrire une fonction
max_pile
qui prend pour argument une pilep
et un entieri
. Cette fonction renvoie la positionj
de l'élément maximum parmi lesi
premiers éléments au sommet de la pilep
. Après l'appel de cette fonction, la pilep
doit avoir retrouvé son état d'origine. La positiion du sommet de la pile est 1.1 2
print(max_pile(q, 2)) affiche_pile(q)
1 | 8 | -> sommet | 5 | | 2 | | 4 | -----
-
Écrire une fonction
retourner
qui prend en argument une pilep
et un entierj
et inverse l'ordre desj
éléments au sommet de la pilep
.Remarque. Si on dépile tout
p
dansq1
, les éléments deq
apparaissent dans l'ordre inverse que dansp
. Si on dépile toutq1
dansq2
, les éléments apparaissent dansq2
dans le même ordre que dansp
. Si on dépileq2
dansp
, les éléments dep
sont dans l'ordre inverse par rapport à la situation initiale.1 2
retourner(q, 3) affiche_pile(q)
| 2 | -> sommet | 5 | | 8 | | 4 | -----
-
On cherche à trier une pile d'entiers, avec la méthode dite du "tri crêpe". L'idée est de procéder à des retournements successifs de la pile, comme on le ferait avec une spatule.
Le principe est le suivant :
- On recherche le plus grand élément \(M\) parmi les \(n\) éléments qui la composent.
- On retourne le morceau de la pile compris entre le sommet de la pile et \(M\). Celui-ci se retrouve donc au sommet de la pile.
- On retourne toute la pile. \(M\) est donc tout en bas de la pile, il est correctement placé.
- On réitère ce procédé avec \(n - 1\) éléments au sommet de la pile.
Écrire une fonction
tri_crepe
qui trie une pilep
suivant cet algorithme.
Type bac II¶
On considère la file f
suivante :
--------------------------------------
enfilement -> "rouge" "vert" "jaune" "rouge" "jaune" -> défilement
--------------------------------------
-
Écrire le code python permettant d'instancier une variable
f
de typeFile
correspondant à la filef
de l'énoncé. -
Quel sera le contenu de la pile
p
et de la filef
après l’exécution du programme Python suivant?1 2 3
p = creer_pile_vide() while not(est_file_vide(f)): empiler(p, defiler(f))
-
Créer une fonction
taille_file
qui prend en paramètre une filef
et qui renvoie le nombre d’éléments qu’elle contient. Après appel de cette fonction la filef
doit avoir retrouvé son état d’origine.1 2 3
def taille_file(): """File -> int""" pass
Ainsi, si
f
est la file de la question 1, alors on doit avoir :
1 2 |
|
5
--------------------------------------
enfilement -> "rouge" "vert" "jaune" "rouge" "jaune" -> défilement
--------------------------------------
-
Écrire une fonction
former_pile
qui prend en paramètre une filef
et qui renvoie une pilep
contenant les mêmes éléments que la file.Le premier élément sorti de la file devra se trouver au sommet de la pile; le deuxième élément sorti de la file devra se trouver juste en-dessous du sommet, etc.
Ainsi, si
f
est la file de la question 1, alors l’appelformer_pile(f)
va renvoyer la pilep
ci-dessous :| "jaune" | -> sommet | "rouge" | | "jaune" | | "vert" | | "rouge" | -----------
-
Écrire une fonction
nb_elements
qui prend en paramètres une filef
et un élémentelt
et qui renvoie le nombre de fois oùelt
est présent dans la filef
. Après appel de cette fonction la filef
doit avoir retrouvé son état d’origine.1 2 3
def nb_elements(f, elt): """ File, int -> int """ pass
Ainsi, si
f
est la file de la question 1, alors on doit avoir :1 2
print(nb_elements(f, "jaune")) affiche_file(f)
2 -------------------------------------- enfilement -> "rouge" "vert" "jaune" "rouge" "jaune" -> défilement --------------------------------------
-
Écrire une fonction
verifier_contenu
qui prend en paramètres une filef
et trois entiers:nb_rouge
,nb_vert
etnb_jaune
. Cette fonction renvoieTrue
si"rouge"
apparaît au plusnb_rouge
fois dans la filef
et si"vert"
apparaît au plusnb_vert
fois dans la filef
et si"jaune"
apparaît au plusnb_jaune
fois dans la filef
. Elle renvoieFalse
dans tous les autres cas. On pourra utiliser les fonctions précédentes.
Documents¶
On pourra télécharger le fichier python de l'interface et commencer les fichiers par
1 |
|
afin d'importer les fonctions utilisées dans cette feuille d'exercice.