pilespc.fermat.free.fr/python/pilesdiapo.pdf · 2020. 8. 31. · defcree_pile(): return[] defempile...

55
Piles Lycée Fermat Cours d’informatique PC 2020/2021 1/50

Upload: others

Post on 07-Feb-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

  • Piles

    Lycée Fermat

    Cours d’informatique PC2020/2021

    1/50

  • Plan du chapitre

    1 Piles

    2 Exemples d’utilisation

    2/50

  • Stockage des données informatiques

    Stockage efficace de données ?

    La notion d’efficacité dépend de ce que l’on cherche à faire avec cesdonnées :

    l’ensemble des ces données est-il statique (ne varie pas au cours dutemps) ou dynamique ?doit-on pouvoir accéder facilement à chacune des données, ou suffit-ilde pouvoir les traiter dans l’ordre dans lequel elles apparaissentnaturellement ?dans le cas où l’ensemble des données évolue, doit-on pouvoir accéderfacilement à la dernière donnée insérée dans l’ensemble ou lapremière ?. . .

    3/50

  • Structures linéaires

    Structure de données déjà rencontrée : liste/tableau. Les données sontstockées linéairement ;accessibles en temps constant grâce à la position de l’élément dans laliste.

    Pile : nouvelle structure de donnéeslinéaire ;qui ne permet l’accès qu’à un élément de la pile.

    4/50

  • Structures linéaires

    Structure de données déjà rencontrée : liste/tableau. Les données sontstockées linéairement ;accessibles en temps constant grâce à la position de l’élément dans laliste.

    Pile : nouvelle structure de donnéeslinéaire ;qui ne permet l’accès qu’à un élément de la pile.

    4/50

  • Structures non linéaires

    Il existe des structures de données non linéaires : les arbres par exemple.Dans une telle structure, chaque élément n’a pas un prédécesseur et unsuccesseur, mais un parent et des fils.

    5/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    1 Piles 6/50

  • Une image du type pile

    Une pile est une structure de données dont une bonne image est celled’une pile d’assiettes : on peut

    ajouter une assiette sur la pile ;retirer l’assiette du dessus.

    1 Piles 7/50

  • Définition de la structure de pile

    Une pile est une structure de données dont les fonctions de manipulationsse résument aux trois fonctions suivantes :

    une fonction de création d’une pile (initialement vide) ;une fonction d’ajout d’un élément à une pile existante (on ditempiler) ;une fonction d’extraction du dernier élément ajouté à la pile (on ditdépiler).

    Une telle structure est qualifiée de LIFO (Last In – First Out).

    On exige que chacune de ces trois opérations s’effectue en temps constant.

    1 Piles 8/50

  • D’autres fonctions de manipulation

    On ajoute parfoistester si la pile est vide (préférable avant de tenter de dépiler) ;consulter l’élément au sommet de la pile, mais sans l’extraire.

    1 Piles 9/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    1 Piles 1.1 Piles à hauteur bornée 10/50

  • Cas où la taille maximale est connue

    On peut utiliser un tableau pour représenter une pile : la première casecontient la hauteur effective h (le nombre d’éléments effectivement stockésdans la pile).

    dépilement : renvoyer l’élément en position h et remplacer h par h−1 ;empilement : placer le nouvel élément en position h + 1 et remplacerh par h + 1.

    Il faut s’assurer que la pile n’est pasvide (cas du dépilement) ;pleine (cas de l’empilement).

    1 Piles 1.1 Piles à hauteur bornée 11/50

  • Implémentation

    def stack(N):""" crée une pile vide de taille N (la premièrecase indique le nombre d’éléments stockésdans la pile)"""p = [None] * (N+1)p[0] = 0return p

    Par exemple :

    >>> p = stack (10)>>> p[0, None , None , None , None , None , None , None , None ,

    None , None]

    1 Piles 1.1 Piles à hauteur bornée 12/50

  • Fonction d’empilement

    Commencer par s’assurer qu’il reste de la place.Si c’est le cas, on place l’élément x en position n + 1 et on augmente p0d’une unité.

    def push(x,p):""" empile un élément au sommet de la pile(si elle n’est pas pleine )"""n = p[0]assert (n < len(p)-1)p[0] = n+1p[n+1] = x

    La fonction ne renvoie rien : elle se contente de modifier la pile !

    1 Piles 1.1 Piles à hauteur bornée 13/50

  • Exemple d’empilement

    >>> push (5,p)>>> push (-8,p)>>> p[2, 5, -8, None , None , None , None , None , None , None ,

    None]

    1 Piles 1.1 Piles à hauteur bornée 14/50

  • Dépilement

    Commencer par s’assurer que la pile est non vide.Si c’est le cas, on diminue p0 d’une unité et on renvoie l’élément enposition n.

    def pop(p):""" extrait le sommet de la pile(si elle est non vide) et le renvoie """n = p[0]assert (n > 0)p[0] = n-1return p[n]

    1 Piles 1.1 Piles à hauteur bornée 15/50

  • Exemple de dépilement

    >>> pop(p)-8

    >>> p[1, 5, -8, None , None , None , None , None , None , None ,

    None]

    L’élément −8 (au sommet de la pile) a bien été renvoyé, mais pasréellement supprimé de la pile.

    1 Piles 1.1 Piles à hauteur bornée 16/50

  • Empilement d’un nouvel élément

    >>> push (17,p)>>> p[2, 5, 17, None , None , None , None , None , None , None ,

    None]

    1 Piles 1.1 Piles à hauteur bornée 17/50

  • Test de vacuité et consultation du sommet

    def is_empty (p):return p[0] == 0

    def top(p):n = p[0]assert (n > 0)return p[n]

    Chacune des opérations d’empilement et de dépilement est effectuée entemps constant.Inconvénient : caractère borné de la pile.

    1 Piles 1.1 Piles à hauteur bornée 18/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    1 Piles 1.2 Piles à hauteur non bornée 19/50

  • Notion de liste

    En informatique, une liste désigne une structure de donnéelinéaire ;dans laquelle les éléments ne sont pas stockés de façon consécutive :chaque élément de la liste connaît l’adresse de son prédécesseur.

    Intérêt : taille non limitée à la création. Pour ajouter un élément, il suffitde stocker à un endroit disponible dans la mémoire cet élément, ainsi quel’adresse de son prédécesseur (le dernier élément de la liste à laquelle onveut ajouter un élément).

    Ainsi, ce que l’on appelle liste en python est en réalité un tableau : leséléments sont stockés de façon consécutives ; on accède en temps constantà chacun via son numéro.

    1 Piles 1.2 Piles à hauteur non bornée 20/50

  • Notion de liste

    En informatique, une liste désigne une structure de donnéelinéaire ;dans laquelle les éléments ne sont pas stockés de façon consécutive :chaque élément de la liste connaît l’adresse de son prédécesseur.

    Intérêt : taille non limitée à la création. Pour ajouter un élément, il suffitde stocker à un endroit disponible dans la mémoire cet élément, ainsi quel’adresse de son prédécesseur (le dernier élément de la liste à laquelle onveut ajouter un élément).

    Ainsi, ce que l’on appelle liste en python est en réalité un tableau : leséléments sont stockés de façon consécutives ; on accède en temps constantà chacun via son numéro.

    1 Piles 1.2 Piles à hauteur non bornée 20/50

  • Qu’est réellement une liste Python ?

    La méthode append permet d’ajouter un élément à une liste python !

    Raison : une liste python est en fait un tableau dans lequel on a réservé dela place pour ajouter de nouveaux éléments (comme nos piles !).

    1 Piles 1.2 Piles à hauteur non bornée 21/50

  • Cas d’un tableau plein

    Lorsque l’on veut ajouter un nouvel élément alors que le tableau est plein,on crée une copie du tableau plein, dans un nouveau tableau, deux foisplus grand.Cette opération

    a un coût non négligeable (recopier tous les éléments du tableauinitial) ;n’intervient que de façon exceptionnelle !

    En moyenne (sur une succession de n ajouts), tout se passe comme si lecoût de chaque ajout était borné (on parle de complexité amortie bornée).

    1 Piles 1.2 Piles à hauteur non bornée 22/50

  • Représentation des piles par des listes

    Nous représenterons les piles par des listes python. Fonctionempiler : méthode append ;dépiler : méthode pop.

    1 Piles 1.2 Piles à hauteur non bornée 23/50

  • Définition des fonctions de manipulation

    def cree_pile ():return []

    def empile (x, p):p. append (x)

    def depile (p):assert (len(p) > 0)return p.pop ()

    1 Piles 1.2 Piles à hauteur non bornée 24/50

  • Les fonctions supplémentaires

    def est_vide (p):return len(p) == 0

    def sommet (p):n = len(p)assert (n > 0)return p[n -1]

    1 Piles 1.2 Piles à hauteur non bornée 25/50

  • Exemple d’utilisation

    >>> p = cree_pile ()>>> p[]

    >>> for i in range (3):... empile (i,p)>>> p[0, 1, 2]

    >>> depile (p)2

    >>> p[0, 1]

    1 Piles 1.2 Piles à hauteur non bornée 26/50

  • Exemple d’utilisation

    >>> p = cree_pile ()>>> p[]

    >>> for i in range (3):... empile (i,p)>>> p[0, 1, 2]

    >>> depile (p)2

    >>> p[0, 1]

    1 Piles 1.2 Piles à hauteur non bornée 26/50

  • Exemple d’utilisation

    >>> p = cree_pile ()>>> p[]

    >>> for i in range (3):... empile (i,p)>>> p[0, 1, 2]

    >>> depile (p)2

    >>> p[0, 1]

    1 Piles 1.2 Piles à hauteur non bornée 26/50

  • Exemple d’utilisation

    >>> p = cree_pile ()>>> p[]

    >>> for i in range (3):... empile (i,p)>>> p[0, 1, 2]

    >>> depile (p)2

    >>> p[0, 1]

    1 Piles 1.2 Piles à hauteur non bornée 26/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    1 Piles 1.3 Files 27/50

  • Une autre structure linéaire

    File : structure de type FIFO (First In – First Out) : c’est le premierélément qui a été inséré qui sera extrait le premier. Une bonne image estcette fois-ci une file d’attente à un guichet.

    Opérations de manipulation :l’enfilage (en fin de file) ;le défilage (de l’élément en tête de file).

    On exige que ces opérations se fassent en temps constant.

    1 Piles 1.3 Files 28/50

  • Implémentation avec des listes python

    La méthode append permet d’ajouter (en temps amorti constant) unélément en queue de liste ;la méthode pop(0) permet de renvoyer l’élément de position 0 et dele supprimer de la liste.

    Cette dernière opération ne se fait pas en temps constant : supprimer latête de la liste revient en fait à décaler d’une case vers la gauche tous lesautres éléments de la liste.

    On peut proposer d’autres implémentations des files, sur lesquelles nousn’insisterons pas.

    1 Piles 1.3 Files 29/50

  • Le problème de Josèphe

    Exercice 1En utilisant une file, écrire une fonction josephe(n) qui donne le numérode la dernière personne restant en jeu dans le problème de Josèphe.

    1 Piles 1.3 Files 30/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    2 Exemples d’utilisation 31/50

  • Récursivité

    Les fonctions récursives utilisent des piles pour stocker l’environnement dela fonction lorsqu’un appel récursif est effectué.

    Non accessible à notre niveau.

    2 Exemples d’utilisation 32/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    2 Exemples d’utilisation 2.1 Parenthésage 33/50

  • Présentation du problème

    On dispose d’une chaîne de caractères, dont certains sont des parenthèses(ouvrantes ou fermantes). On souhaite vérifier que le parenthésage estcohérent.

    2 Exemples d’utilisation 2.1 Parenthésage 34/50

  • Principe de l’algorithme

    On parcourt la chaîne de caractères. Lorsque l’on rencontre une parenthèseouvrante, on l’empile sur la pile ;fermante, on dépile.

    Le parenthésage est cohérent si, et seulement si,la pile n’était jamais vide lorsque l’on dépilait ;à la fin du parcours, la pile est vide.

    2 Exemples d’utilisation 2.1 Parenthésage 35/50

  • Le programme

    def parenthesage_correct (texte ):p = cree_pile ()for c in texte:

    if c == ’(’:empile (c,p)

    elif c == ’)’:if est_vide (p):

    return Falseelse:

    depile (p)return est_vide (p)

    2 Exemples d’utilisation 2.1 Parenthésage 36/50

  • Des tests

    >>> parenthesage_correct (’ce (petit) texte est(( vraiment ) très) bien parenth ésé’)

    True

    >>> parenthesage_correct (’celui -ci non :-(’)False

    2 Exemples d’utilisation 2.1 Parenthésage 37/50

  • Inutilité d’une pile

    Seuls rensignements intéressants :la hauteur de la pile est-elle toujours positive ou nulle ?la hauteur est-elle nulle à la fin du parcours ?

    On peut se contenter d’une variable h au lieu d’une pile !

    2 Exemples d’utilisation 2.1 Parenthésage 38/50

  • Parenthésage sans pile

    def parenthesage_correct (texte ):h = 0for c in texte:

    if c == ’(’:h += 1

    elif c == ’)’:if h == 0:

    return Falseelse:

    h -= 1return h == 0

    2 Exemples d’utilisation 2.1 Parenthésage 39/50

  • Parenthèses de différentes tailles

    Exercice 2Généralisation : trois types de parenthèses

    ( (niveau 1) ;[ (niveau 2) ;{ (niveau 3).

    On ne peut insérer un couple de parenthèses de niveau n à l’intérieur d’uncouple de niveau p que si p > n. Écrire une fonctionparenthesage_general qui indique si un texte est correctementparenthésé.

    2 Exemples d’utilisation 2.1 Parenthésage 40/50

  • 1 Piles1.1 Piles à hauteur bornée1.2 Piles à hauteur non bornée1.3 Files

    2 Exemples d’utilisation2.1 Parenthésage2.2 Évaluation d’une expression arithmétique

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 41/50

  • Expression arithmétique

    Appelons expression arithmétique (simplifiée) toute expression obtenue, àpartir des entiers, par application des opérateurs binaires +,−,× et de lafonction f : x 7→ x2. Par exemple,

    f (2× (3− 1)) + (7− 8) (1)

    est une expression arithmétique.

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 42/50

  • Représentation infixe

    La représentation précédente est dite infixe : lessymboles de fonction sont placés devant leur argument ;opérateurs binaires entre leurs arguments.

    Inconvénients : nécessitedes parenthèses ;des priorités associées aux opérations.

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 43/50

  • Représentation arborescente

    La même formule représentée par un arbre :

    +

    f

    ×

    2 −

    3 1

    7 8

    Figure 1 : Représentation arborescente d’une formule arithmétique

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 44/50

  • Représentation postfixe

    La même formule représentée sous forme postfixe :

    2 3 1 − × f 7 8 − +

    Lessymboles de fonction sont placés après leur argument ;opérateurs binaires après leurs deux arguments.

    Avantage : ne nécessite ni parenthèses, ni priorités associées auxopérations !

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 45/50

  • Évaluation d’une expression postfixée

    Au début du calcul, la pile est vide. On parcourt la représentation postfixede la formule :

    lorsque l’on rencontre un nombre, on l’empile ;lorsque l’on rencontre une fonction, il faut l’appliquer à l’argumentqui figure juste avant (qui peut être lui-même le résultat d’un calcul ;ce résultat doit figurer au sommet de la pile) : on dépile l’élément ausommet de la pile, on lui applique la fonction et on empile le résultat ;lorsque l’on rencontre un opérateur binaire, il faut l’appliquer aux deuxarguments qui précèdent : on dépile les deux éléments du sommet dela pile, on leur applique l’opérateur et on empile le résultat.

    À la fin du parcours de l’expression, la pile contient une unique donnée : lavaleur de l’expression.

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 46/50

  • Représentation des expressions

    Problème «technique» : que représente la chaîne 11 ?le nombre 11 ?la succession des deux nombres 1 ?

    Il faut des délimiteurs de symboles.

    Solution : une expression arithmétique postifixée est représentée par uneliste de symboles (trois types : nombre, fonction ou opérateurs). Lessymboles +, −, × et la fonction d’élévation au carré seront codés par leschaînes de caractères +, -, * et f.

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 47/50

  • Le programme (I)

    def evalue (expr ):calcul = cree_pile ()for s in expr:

    if s == ’+’:y = depile ( calcul )x = depile ( calcul )empile (x+y, calcul )

    elif s == ’-’:y = depile ( calcul )x = depile ( calcul )empile (x-y, calcul )

    elif s == ’*’:y = depile ( calcul )x = depile ( calcul )empile (x*y, calcul )

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 48/50

  • Le programme (II)

    elif s == ’f’:x = depile ( calcul )empile (x*x, calcul )

    else:empile (s, calcul )

    return depile ( calcul )

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 49/50

  • Un test

    >>> expr = [2, 3, 1, ’-’, ’*’, ’f’, 7, 8, ’-’, ’+’]>>> evalue (expr)15

    2 Exemples d’utilisation 2.2 Évaluation d’une expression arithmétique 50/50

    PilesPiles à hauteur bornéePiles à hauteur non bornéeFiles

    Exemples d'utilisationParenthésageÉvaluation d'une expression arithmétique