Skip to main content

Welcome to a Grasp lesson

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

Lesson 76

Traçage Manuel d'Algorithme

Recommended resources

Bonjour !

Dans la leçon précédente, nous avons écrit l'intégralité du pseudo-code pour notre "Gestionnaire de Contacts Simplifié". Nous avons maintenant un plan d'exécution complet, de la structure des données aux fonctions modulaires, en passant par le programme principal qui orchestre le tout.

Mais un plan, aussi détaillé soit-il, peut contenir des erreurs. Comment être sûr que notre logique est correcte avant même d'écrire une seule ligne de Java ? C'est l'objet de notre leçon aujourd'hui. L'objectif est de valider la logique de l'algorithme en le traçant manuellement avec un jeu de données de test.

Cette technique, appelée "trace d'exécution" ou "test à la main", consiste à se comporter comme l'ordinateur : exécuter chaque instruction une par une et suivre l'évolution des variables. C'est une compétence fondamentale qui vous aidera non seulement à vérifier vos algorithmes, mais aussi à débusquer des bugs complexes plus tard dans votre carrière.

1. La Méthode : Le Tableau de Trace

Pour exécuter un algorithme manuellement, il faut être méthodique. L'outil principal pour cela est le tableau de trace. Il s'agit d'un simple tableau où :

  • Chaque colonne représente une variable de votre algorithme (y compris les variables locales aux fonctions).
  • Une colonne supplémentaire est souvent ajoutée pour noter ce qui est affiché à l'écran (Sortie ou Ecran).
  • Chaque ligne représente une étape de l'exécution, montrant l'état des variables après l'exécution d'une instruction.

Pour commencer, lisons une introduction à cette technique.

[PDF] INITIATION À L'ALGORITHMIQUE EN CLASSE DE SECONDE

Le document 'INITIATION À L'ALGORITHMIQUE' explique très bien le principe de l'exécution manuelle. Il vous montrera comment mettre en place un tableau de trace et l'utiliser sur un exemple concret.

Lisez la section 1.9, intitulée 'Exécution « manuelle » d’un algorithme'. Observez attentivement le tableau fourni en exemple. Notez comment chaque ligne correspond à une opération et comment les valeurs des variables 'a', 'b', et 'reste' changent au fil du temps. C'est exactement ce que nous allons faire.

Comme vous l'avez vu, le processus est simple mais rigoureux :

  1. Lister les variables à suivre dans les en-têtes des colonnes.
  2. Choisir un jeu de données de test (les valeurs d'entrée).
  3. Exécuter chaque instruction dans l'ordre, en mettant à jour la valeur de la variable concernée dans la ligne correspondante du tableau.
  4. Suivre le flux de contrôle : entrer dans les boucles, respecter les conditions SI, et suivre les appels de fonction.

Voici un exemple visuel très simple qui illustre ce principe :

Trace Table Example for Algorithm Validation
Un algorithme simple (à gauche) et sa trace d'exécution (à droite). La table suit les variables 'number', 'i' (le compteur de boucle) et la 'Output' (sortie à l'écran) à chaque étape.

2. Mise en Pratique : Traçons notre Projet

Appliquons maintenant cette méthode à notre projet de gestionnaire de contacts. Nous allons simuler un scénario d'utilisation complet et suivre ce qui se passe "sous le capot".

Scénario de test n°1 : Ajout d'un premier contact

  • État initial : L'annuaire est vide. nb_contacts_actuels = 0.
  • Action de l'utilisateur : Choisit l'option 'A' (Ajouter), puis entre le nom "Dupont", le prénom "Jean" et le téléphone "0123456789".

Nous allons créer un tableau de trace pour suivre les variables importantes : choix_utilisateur, nb_contacts_actuels, et les variables locales des fonctions que nous appellerons. Pour annuaire, nous noterons simplement les changements sur le premier élément annuaire[1].

Voici la trace commentée, étape par étape. Essayez de suivre la logique dans le pseudo-code de la leçon précédente.

Instruction / Opération choix_utilisateur nb_contacts_actuels indice_trouve annuaire[1].nom annuaire[1].prenom annuaire[1].telephone Sortie à l'écran
--- DEBUT Programme Principal ---
nb_contacts_actuels ← 0 ' ' 0 - - - -
TANT QUE choix <> 'Q' (Vrai) ' ' 0 - - - -
AfficherMenu() ' ' 0 - - - - (Le menu s'affiche)
Lire choix_utilisateur 'A' 0 - - - - Votre choix ?
SI choix = 'A' (Vrai) 'A' 0 - - - -
Appel AjouterContact(annuaire, nb_contacts_actuels) 'A' 0 - - - -
-- Entrée dans AjouterContact --
SI nb >= 100 (Faux car 0 < 100)
Lire nouveau_nom ("Dupont") Saisir le nom :
Lire nouveau_prenom ("Jean") Saisir le prénom :
Appel RechercherContact(...)
-- Entrée dans RechercherContact, nb=0 --
POUR i DE 1 A 0 (La boucle ne s'exécute pas)
Retourner -1
-- Retour à AjouterContact -- -1
indice_trouve ← -1 -1
SI indice_trouve <> -1 (Faux) -1
Lire nouveau_tel ("0123456789") -1 Saisir le numéro de téléphone :
nb ← nb + 1 'A' 1 -1
ann[1].nom ← "Dupont" 'A' 1 -1 "Dupont" - -
ann[1].prenom ← "Jean" 'A' 1 -1 "Dupont" "Jean" -
ann[1].telephone ← "0123456789" 'A' 1 -1 "Dupont" "Jean" "0123456789"
Ecrire "Contact ajouté..." 'A' 1 -1 "Dupont" "Jean" "0123456789" Contact ajouté avec succès.
-- Fin de AjouterContact --
--- Retour au Programme Principal --- 'A' 1 - "Dupont" "Jean" "0123456789"
FINTANTQUE (boucle recommence) 'A' 1 - "Dupont" "Jean" "0123456789"

Résultat : La trace confirme que notre algorithme ajoute correctement un contact dans un annuaire vide. La variable nb_contacts_actuels est bien passée de 0 à 1, et les informations sont stockées dans annuaire[1].


3. À vous de jouer !

Maintenant, c'est votre tour d'être l'ordinateur. Utilisez la même méthode pour valider la logique de deux autres scénarios cruciaux.

Exercice 1 : Gérer un doublon

  • État initial : L'annuaire contient déjà un contact : annuaire[1] est ("Dupont", "Jean", "0123456789") et nb_contacts_actuels = 1.
  • Action de l'utilisateur : Tente d'ajouter à nouveau le même contact ("Dupont", "Jean").

Votre mission : Créez un tableau de trace pour ce scénario. Quelles instructions sont exécutées ? Que renvoie la fonction RechercherContact cette fois-ci ? Quel message est affiché à l'utilisateur ? Quelle est la valeur finale de nb_contacts_actuels ?

Cliquez ici pour voir la solution et comparer votre trace.
Instruction / Opération choix_utilisateur nb_contacts_actuels indice_trouve Sortie à l'écran
... (Début de boucle principale) ...
Lire choix_utilisateur 'A' 1 - Votre choix ?
Appel AjouterContact(annuaire, 1) 'A' 1 -
-- Entrée dans AjouterContact --
SI nb >= 100 (Faux)
Lire nouveau_nom ("Dupont") Saisir le nom :
Lire nouveau_prenom ("Jean") Saisir le prénom :
Appel RechercherContact(annuaire, 1, "Dupont", "Jean")
-- Entrée dans RechercherContact --
POUR i DE 1 A 1
i=1 : SI ann[1].nom = "Dupont" ET ... (Vrai)
Retourner 1 (indice du contact trouvé)
-- Retour à AjouterContact -- 1
indice_trouve ← 1 1
SI indice_trouve <> -1 (Vrai car 1 <> -1) 1
Ecrire "Erreur : Ce contact existe déjà." 1 Erreur : Ce contact existe déjà.
-- Fin de AjouterContact --
--- Retour au Programme Principal --- 'A' 1 -

Analyse : La trace montre que RechercherContact a bien trouvé le doublon et a renvoyé son indice (1). L'algorithme a donc correctement affiché le message d'erreur et, surtout, n'a PAS incrémenté nb_contacts_actuels, qui reste à 1. La logique est validée.

Exercice 2 : Suppression d'un contact

La suppression implique une manipulation de tableau (décalage des éléments) qui mérite d'être vérifiée attentivement.

Worked Example: Tracing Nested Loops
Tracer des boucles, comme celle pour décaler les éléments, demande de la rigueur. Chaque passage dans la boucle est une nouvelle ligne dans votre tableau de trace.
  • État initial : L'annuaire contient deux contacts :
    1. ("Durand", "Alice", "06...")
    2. ("Lefebvre", "Marc", "07...")
      nb_contacts_actuels = 2.
  • Action de l'utilisateur : Choisit l'option 'S' (Supprimer) et entre le nom "Durand" et le prénom "Alice".

Votre mission : Réalisez la trace d'exécution de la procédure SupprimerContact. Suivez attentivement la boucle de décalage. Que contient annuaire[1] à la fin ? Quelle est la nouvelle valeur de nb_contacts_actuels ?

Cliquez ici pour voir la solution.
Instruction / Opération nb_contacts_actuels indice_a_supprimer annuaire[1] annuaire[2] Sortie à l'écran
État initial 2 - Durand, Alice Lefebvre, Marc
Appel SupprimerContact(...) 2 - Durand, Alice Lefebvre, Marc Saisir nom/prénom...
indice_a_supprimer ← RechercherContact(...) (renvoie 1) 2 1 Durand, Alice Lefebvre, Marc
SI indice_a_supprimer = -1 (Faux) 2 1 Durand, Alice Lefebvre, Marc
POUR i DE 1 A 1 (nb - 1 = 2 - 1 = 1) 2 1 Durand, Alice Lefebvre, Marc
i=1 : ann[1] ← ann[2] 2 1 Lefebvre, Marc Lefebvre, Marc
FINPOUR 2 1 Lefebvre, Marc Lefebvre, Marc
nb ← nb - 1 1 1 Lefebvre, Marc Lefebvre, Marc
Ecrire "Contact supprimé..." 1 1 Lefebvre, Marc Lefebvre, Marc Contact supprimé avec succès.
Fin 1 - Lefebvre, Marc -

Analyse : La trace valide plusieurs points importants.

  1. Le contact à supprimer est bien trouvé à l'indice 1.
  2. La boucle de décalage (POUR i DE 1 A 1) s'exécute une seule fois.
  3. L'instruction ann[1] ← ann[2] écrase bien "Durand, Alice" par "Lefebvre, Marc".
  4. Le nombre de contacts est correctement décrémenté à 1.
    L'annuaire ne contient plus que "Lefebvre, Marc" à la première position, ce qui est le comportement attendu.

Conclusion

Félicitations ! Vous venez d'acquérir une compétence de "débogueur manuel". En traçant votre algorithme, vous avez non seulement validé sa logique, mais vous avez aussi acquis une compréhension intime de son fonctionnement, bien plus profonde qu'en le lisant simplement.

Points clés à retenir :

  • La trace d'exécution est une méthode rigoureuse pour vérifier la logique d'un algorithme avant de le coder.
  • Le tableau de trace est l'outil central qui permet de suivre l'état de chaque variable, instruction par instruction.
  • Les cas de test sont essentiels. Il faut tester non seulement le "cas nominal" (où tout se passe bien) mais aussi les cas limites et les cas d'erreur (doublons, annuaire vide/plein, etc.).

Notre algorithme semble robuste et correct. Mais est-il efficace ? La recherche d'un contact dans un annuaire de 100 entrées est rapide, mais qu'en serait-il avec 100 000 entrées ? Le temps d'exécution deviendrait-il un problème ?

Dans la prochaine leçon, nous entrerons dans le monde de l'analyse de performance en apprenant à analyser la complexité temporelle de notre solution finale. Cela nous permettra de mesurer objectivement l'efficacité de notre algorithme.