Aller au contenu

Implémentation avec tableau

Le cadre

Dans certains langages de programmation, il n'y a pas de listes dynamiques, mais plutôt des tableaux. Rappelons qu'ils sont de taille fixe et contiennent des éléments homogènes.

Dans le cadre de cet exercice, nous allons certes utiliser les listes dynamiques de Python, mais en nous restreignant volontairement pour simuler l'utilisation de tableaux.

Objectif
Construire une classe Pile dont le support des données sera dans un tableau prédéfini. Une limitation évidente sera la taille maximale de toute pile créée.
Limitations

On peut certes écrire facilement cette implémentation avec un langage de programmation plus rudimentaire comme le C, mais il faudra considérer :

  • La pile aura une taille maximale prédéfinie.
  • La structure de la pile consommera toujours la même quantité de mémoire ; comme si elle était toujours pleine.
  • Les éléments devront être aussi de taille constante et rudimentaires. Si on veut des éléments de taille variable, il faudra utiliser une pile d'adresses (des références) vers les éléments de taille variable.

Exercice

On donne le début d'une classe Pile :

🐍 Script Python
class Pile():
    """Classe Pile avec tableaux Python"""

    def __init__(self, taille_max: int):
        self.taille_max = taille_max
        self.données = [None] * taille_max  # un tableau
        self.i = 0

Compléter la classe Pile (est_vide, empile et dépile) :

  • L'initialiseur prend taille_max en paramètre, et crée une pile vide.
    • qui s'appuie sur un tableau de données, initialement rempli de None.
  • On peut empiler jusqu'à atteindre la taille_max,
  • mais tenter d'empiler un élément de plus provoquera raise ValueError("Pile pleine !")
  • Si on dépile, on remplacera la donnée dans le tableau par None.
  • Tenter de dépiler alors que la pile est vide provoquera raise ValueError("Pile vide !")
  • L'attribut self.i indique :
    • l'indice du tableau où on va empiler le prochain élément,
    • mais également la taille réelle de la pile.
    • Enfin, si on peut dépiler, l'élément se trouve à l'indice précédent.
Justification de ValueError

Les cas d'erreurs (on tente de défiler depuis une pile vide, ou on tente d'empiler sur une pile pleine) sont gérés explicitement avec raise ValueError("message") ce choix est motivé par le comportement de Python si on cherche à faire min (ou max) sur une liste vide.

On aurait pu choisir IndexError qui correspond à un pop sur une liste vide... Ou bien KeyError dans d'autres situations...

Pourquoi pas IndexError ? Une pile pourrait certes être munie d'indices, c'est presque naturel ! Mais non, donc non, ce n'est pas l'esprit d'une pile.

###(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
Évaluations restantes : /
.128013x/.rnbylaeu)dV63Am(P+02è-],59f!78 N_o=pcwgv41`kRéhtsSj[i:E050n0k0Z0j0(0i0!0I0O0i0j0!0!0M010Z0(0N010406050!0l0s0s0j0e0h040#0L0i0l0~0L0f050c1517191b130N04051r1k1u0c1r130n0(0R0?0^0`0|0Y0(0Q0Y0i1I0Y0Z11050.0g0i0k1D0_0{011H1J1L1J0Z1R1T1P0Z0e1s0Z0Y1V1F010E0:0k0f0j0s0k010?1e0!0N0j0f0|0x1P20221:1X1?1T1_1{110a0I0u0e0L0N0L0!0(1h0f0I0,1~0e0e0k0O2p1k270f1s0c1.2C1+1-1,1Q0n290|1L0f1^2m1P1A1C0@1W2M0(2O0f0L2S1P0N2v1s2A2C2*14212q2U1;2Z0e180i110I0T2z2.122-282:1X2=2@2_0x2|222~2A2L01330j2^040I0q372B133a310|3d3f0I0S3j392.3b3p2_0C3t3l3v3n3c0L2?3e2_0p3A2 2/1E323F343g0G3K3m3N3o3P3H3g0H3T3C3V3E3G3q0D3#303%3x040T0w3,3M2V3(3Q0T2{1l2}3B3-3^3/0T363}383 3@2;3X3f0T3i453k3L3w4a110T3s4e3u40493)4j3z4m474h4q3:3J4t4g3D423S4z3U414i3:3!4E3$4G4w0T3+4m1v2(1k2S2F0n1-2K3D0O2!1|1s4U1t4S2,4Q4!0,2)4L1;0V110,0E3t4A3%0P2_4_4F2;0E110k0!0Z0K0R0(0,4~4:1X10040t5a4o1X0g5d0!0k0i4^4Q4 5c110m0)3A0I5w0I4`3^0!2504010W1^0R0L0(1U0l2q0g0L1e0X1^015v5x5z4;112v0Z0l0e1j4m5y5q0|5j115l5n5g481X0L110d5/3w110(3t5(5b0|5=040M0M5|5V1X0s0(113=4t4u3D4=044@5^3D4|3g6h3.51040k0s0N1@6l3^5d5f5p5~015+045-5o2,5)015d0B646F0f110X0i0X1{0f0Z6t1;5d5t5T5w650|5B11010r0$0L1g1U0U6N6P1^0Z0U0I0j0l0I0!0L170-2r1U0^0I6r1T0d5S4t5x5}5h0|6e0(6D2}785:5*5k5m7d386Z01605@6x793c5`6J6y60627u7r6A6C6T5;5?7C3o110.0:1T0K180b7F6G115u76775U6F6e0e0/5l7y7g3c4$0o3e0l0k0*2u3F7O6v7O6#5D0u1@711T2X1U0F756E6y6V6X7f3b7A7j7O7o7O6L6f1i0f5Q0!7/110%7O855.7q7#888m5_045{8p3D5d0A7!3b7w8x4B6M6O6Q6S7S6Y6F8k7k2B7m8o7 7r8a8s2*833D600v635%7m674j3A6c3%6e6g8t4{4}8+416n0n0X720k8g5e8j7i8l8O7#6V7R2*06777m7=010*0f0i0y0R1U6}2v0f5H5J0I0i000I6-8D6:6=0n6^6`6|0Z6~9i0j711@74827m7b8K6k8I8{9E8M7E8.2;7t8Y6F7w8X8S8Z68046a8}3b5d903~7T7U6y7W7Y8@9O6y2O117(1f7+7-0e8^6w9X3D957@1T0I572s7}8^0m9B9G5,869L7D047p9`3.9N9S9P110z9R7e9T8#8G8Tae046.8E8A3%8z9,7z9H879Kad414?8c8e8^8ia97ha78|2}9Jab89afaN6F8va56y8JaAaPaJ7s8b0f8d53aH8`aL9IahaZaC9M8r8^8wax8n11ak38ap3^0V0O110J1i9+91937V5X0-5!5$ag9-8C6/6R3K0c4-0k2C2%bk4T1B4V2F2I2D0j1Sbn0c4U13bx0-0/0;04.