Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 36

Utilisation de piles pour l'inversion de chaînes de caractères

Recommended resources

Bonjour ! J'espère que vous êtes prêt(e) pour une nouvelle leçon.

Introduction

Dans la leçon précédente, nous avons découvert la structure de données de la pile et son principe de fonctionnement fondamental : Dernier Arrivé, Premier Sorti (LIFO). Nous avons défini ses opérations essentielles (CreerPile, Empiler, Dépiler, Sommet, PileVide) et vu comment suivre manuellement leur exécution.

Aujourd'hui, nous allons mettre cette connaissance théorique en pratique. L'objectif est d'utiliser une pile pour résoudre un problème simple mais classique : l'inversion d'une chaîne de caractères. Vous allez voir comment le principe LIFO se prête naturellement à cette tâche, ce qui illustre parfaitement la puissance de choisir la bonne structure de données pour résoudre un problème. C'est un pas de plus vers votre objectif d'écrire des algorithmes "clean" et logiques.


1. Le problème : Inverser une chaîne de caractères

Le problème est simple à énoncer. Si on vous donne une chaîne de caractères en entrée, par exemple "BONJOUR", votre algorithme doit produire en sortie la chaîne inversée, c'est-à-dire "RUOJNOB".

Comment y parvenir ? La clé est de trouver un moyen de stocker les caractères dans un certain ordre, pour ensuite les récupérer dans l'ordre inverse. Cela ne vous rappelle rien ? C'est exactement ce que fait une pile grâce à son principe LIFO.


2. L'algorithme d'inversion avec une pile

La logique est directe :

  1. On parcourt la chaîne de caractères originale du début à la fin.
  2. On empile chaque caractère, un par un, sur une pile. Le premier caractère de la chaîne se retrouvera donc tout en bas de la pile, et le dernier tout en haut.
  3. Une fois tous les caractères empilés, on dépile les éléments un par un.
  4. On concatène (ajoute) chaque caractère dépilé à une nouvelle chaîne de résultat. Comme on dépile en partant du sommet (le dernier caractère entré), on reconstruit la chaîne dans l'ordre inverse.

Pour bien visualiser ce processus, je vous propose de consulter la ressource suivante qui l'illustre parfaitement.

Reverse a String - Tutorial - takeuforward

L'article "Reverse a String" de takeuforward.org (malgré son titre en anglais) explique et illustre de manière très claire l'algorithme d'inversion de chaîne avec une pile. Les schémas sont particulièrement utiles.

Lisez la section "Brute force Approach" (qui correspond à notre approche avec une pile). Concentrez-vous sur la liste à puces décrivant l'algorithme et sur la série d'images qui suit. Ces images décomposent le processus d'empilement (push) et de dépilement (pop) pour la chaîne "hello".


3. Visualisation détaillée du processus

Pour nous assurer que le mécanisme est bien compris, traçons manuellement l'inversion de la chaîne "PILE".

L'image ci-dessous illustre la séquence des opérations Push (Empiler) et Pop (Dépiler).

Illustration des Opérations Push et Pop sur une Pile
Cette image montre une séquence d'opérations sur une pile. Les étapes 1 à 5 montrent l'empilement successif d'éléments (Push). Les étapes 6 à 10 montrent le dépilement successif (Pop), libérant les éléments en commençant par le dernier qui a été ajouté.

Appliquons ce principe à notre mot "PILE" :

Étape 1 : Empiler les caractères

Opération État de la pile (Sommet → Base)
Empiler('P') ['P']
Empiler('I') ['I', 'P']
Empiler('L') ['L', 'I', 'P']
Empiler('E') ['E', 'L', 'I', 'P']

À ce stade, la pile contient tous les caractères. Le dernier caractère entré, 'E', est au sommet.

Étape 2 : Dépiler pour construire la chaîne inversée

Opération Caractère dépilé Chaîne résultat État de la pile
Initial - "" ['E', 'L', 'I', 'P']
Dépiler() 'E' "E" ['L', 'I', 'P']
Dépiler() 'L' "EL" ['I', 'P']
Dépiler() 'I' "ELI" ['P']
Dépiler() 'P' "ELIP" [] (vide)

La pile est maintenant vide, et nous avons obtenu la chaîne inversée "ELIP".


4. Algorithme en pseudo-code

Maintenant que la logique est claire, formalisons-la en pseudo-code. Nous allons écrire une fonction InverserChaine qui prend une chaîne en paramètre et retourne la chaîne inversée.

FONCTION InverserChaine(chaine_originale : ChaineDeCaracteres) : ChaineDeCaracteres

    // 1. Déclarations et initialisations
    VAR p : Pile // On déclare une pile
    VAR chaine_inversee : ChaineDeCaracteres
    VAR i : Entier

    p <- CreerPile()
    chaine_inversee <- "" // Initialise une chaîne vide

    // 2. Empiler chaque caractère de la chaîne originale dans la pile
    POUR i DE 0 A Longueur(chaine_originale) - 1 FAIRE
        Empiler(p, caractere_a(chaine_originale, i))
    FIN POUR

    // 3. Dépiler chaque caractère de la pile et l'ajouter à la chaîne de résultat
    TANT QUE PileVide(p) = FAUX FAIRE
        // On lit le sommet, on l'ajoute au résultat, puis on le retire
        chaine_inversee <- chaine_inversee + Sommet(p)
        Dépiler(p)
    FIN TANT QUE

    // 4. Retourner la chaîne inversée
    RETOURNER chaine_inversee

FIN FONCTION

Ce pseudo-code utilise les opérations de pile que nous avons définies dans la leçon précédente. Il est clair, décomposé en étapes logiques, et gère le processus du début à la fin.


5. Exercice pratique

Votre préférence allant à la pratique, je vous propose maintenant de mettre les mains à la pâte. L'exercice suivant est directement tiré d'un document de travaux pratiques.

TP 6 – Piles et fonctions récursives

Le document "TP 6 – Piles et fonctions récursives" propose un exercice simple qui correspond exactement à ce que nous venons d'étudier.

Consultez l'"Exercice 1 — Un peu de verlan". La question 1 vous demande d'écrire un programme pour inverser une chaîne en utilisant une pile.

Votre tâche :
Prenez le pseudo-code de la FONCTION InverserChaine que nous avons écrite ci-dessus et tracez son exécution manuellement avec la chaîne d'entrée "ALGORITHME".

Créez un tableau similaire à celui de la section 3 pour suivre :

  1. L'état de la pile après chaque Empiler.
  2. L'état de la chaine_inversee après chaque Dépiler.

Prenez votre temps pour faire cet exercice. C'est en effectuant ces traces manuellement que l'on ancre solidement la compréhension du mécanisme.


Conclusion

Félicitations ! Vous avez appliqué avec succès votre connaissance des piles pour résoudre un premier problème concret.

Les points clés à retenir :

  • La structure de données de la pile est un outil naturel pour les problèmes qui nécessitent une inversion d'ordre.
  • L'algorithme pour inverser une chaîne consiste à empiler tous ses caractères, puis à les dépiler pour construire la nouvelle chaîne.
  • Tracer manuellement l'exécution d'un algorithme est une compétence fondamentale pour le valider et s'assurer de sa logique.

Le principe LIFO a de nombreuses autres applications, comme la vérification de parenthèses dans une expression mathématique, la navigation "précédent" dans un navigateur web, ou encore la gestion des appels de fonctions par un programme (ce que nous verrons avec la récursivité).


Et après ?

Nous avons exploré une structure de données où le dernier arrivé est le premier servi. Mais que se passe-t-il si l'on veut respecter l'ordre d'arrivée ? Dans la prochaine leçon, nous allons découvrir la structure de la File (Queue), dont le principe est Premier Arrivé, Premier Sorti (FIFO), comme dans une file d'attente classique. Nous définirons ses opérations et la comparerons à la pile.