Exercice — tableau d'enregistrements (5 points), dans l'esprit des sessions 2016–2026
Le comité d'organisation d'un tournoi scolaire de handball planifie les matchs d'une journée dans un tableau T de N matchs (2 ≤ N ≤ 40). Chaque match est un enregistrement formé de trois champs : le libellé Lib du match (une chaîne non vide, par exemple "Sfax-Gabès"), l'heure H du coup d'envoi (un entier de 8 à 22) et la minute Mn (un entier de 0 à 59).
On donne les trois séquences suivantes, censées ranger dans l'ordre chronologique (l'heure H, puis la minute Mn en cas d'égalité des heures) les deux matchs T[0] et T[1] :
Séquence a :
Si (T[0].H > T[1].H) Ou (T[0].Mn > T[1].Mn) Alors
x ← T[0]
T[0] ← T[1]
T[1] ← x
Fin SiSéquence b :
Si (T[0].H > T[1].H) Ou
((T[0].H = T[1].H) Et (T[0].Mn > T[1].Mn)) Alors
x ← T[0]
T[0] ← T[1]
T[1] ← x
Fin SiSéquence c :
Si (T[0].H > T[1].H) Ou
((T[0].H = T[1].H) Et (T[0].Mn > T[1].Mn)) Alors
x ← T[0].H
T[0].H ← T[1].H
T[1].H ← x
x ← T[0].Mn
T[0].Mn ← T[1].Mn
T[1].Mn ← x
Fin SiOn donne aussi, pour N = 6, le tableau T suivant :
| i | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Lib | Sfax-Gabès | Tunis-Nabeul | Sousse-Kef | Bizerte-Béja | Gafsa-Tozeur | Monastir-Mahdia |
| H | 16 | 9 | 16 | 9 | 14 | 16 |
| Mn | 30 | 45 | 0 | 5 | 30 | 30 |
Travail demandé :
- Dresser le tableau de déclaration des nouveaux types : le type enregistrement Match et le type Tab du tableau T, qui peut contenir au plus 40 matchs.
- Soient e1 et e2 deux variables de type Match. Valider chacune des propositions suivantes par la lettre V si elle est correcte ou par la lettre F dans le cas contraire.
- L'instruction
e1 ← e2recopie la valeur de chacun des trois champs de e2 dans le champ correspondant de e1. - L'instruction
e1 ← e2recopie uniquement le premier champ, Lib. - L'instruction
e1 ← e2est incorrecte : il faut affecter les champs un par un. - L'instruction
Si e1 < e2 Alors …compare correctement les horaires de deux matchs.
- L'instruction
- Écrire l'algorithme d'une procédure Saisie(T, N) qui saisit N (2 ≤ N ≤ 40), puis remplit le tableau T en respectant les contraintes de l'énoncé : libellé non vide, heure de 8 à 22 et minute de 0 à 59.
- Séquences a, b et c données ci-dessus.
- Indiquer la seule séquence correcte.
- Pour chacune des deux autres séquences, donner des valeurs de T[0] et T[1] qui la mettent en défaut, et le contenu de T[0] et T[1] qu'elle produit.
- Donner le type de l'objet x dans la séquence correcte.
- Écrire l'algorithme d'une procédure Trier(T, N) qui range les N matchs du tableau T dans l'ordre chronologique : ordre croissant de l'heure H et, en cas d'égalité, ordre croissant de la minute Mn.
- Donner le contenu du tableau T donné ci-dessus après l'appel de Trier(T, 6).
- Écrire l'algorithme d'une procédure Planning(T, N) qui crée et remplit, à la racine du disque D, un fichier texte "Planning.txt" contenant une ligne par match du tableau T déjà trié, au format
hh:mm Lib: l'heure et la minute sont écrites chacune sur deux chiffres, par exemple09:05 Tunis-Nabeul.
NB : chaque solution développée sous forme d'algorithme est accompagnée du tableau de déclaration de ses objets locaux.
Voir la correction commentéeAprès avoir posé votre démarche
1. Idée : on déclare d'abord l'enregistrement, puis le tableau dont les éléments sont de ce type. Les contraintes (8 à 22, 0 à 59) ne se déclarent pas : elles se contrôlent à la saisie.
| Nouveaux types |
|---|
| Match = Enregistrement Lib : Chaîne H : Entier Mn : Entier Fin |
| Tab = Tableau de 40 Match |
2. a : V ; b : F ; c : F ; d : F. L'affectation globale est permise entre deux enregistrements de même type et recopie tous les champs. En revanche, deux enregistrements ne se comparent pas globalement : on compare leurs champs.
3. Idée : une boucle Répéter … Jusqu'à par contrainte, champ par champ, à l'intérieur de la boucle Pour qui parcourt les N cases. T et N sont des résultats de la procédure : ils sont passés par adresse (@).
Procédure Saisie (@ T : Tab, @ N : Entier)
DEBUT
Répéter
Ecrire ("Nombre de matchs : ")
Lire (N)
Jusqu'à (2 ≤ N) Et (N ≤ 40)
Pour i de 0 à N - 1 Faire
Répéter
Ecrire ("Libellé : ")
Lire (T[i].Lib)
Jusqu'à Long (T[i].Lib) > 0
Répéter
Ecrire ("Heure : ")
Lire (T[i].H)
Jusqu'à (8 ≤ T[i].H) Et (T[i].H ≤ 22)
Répéter
Ecrire ("Minute : ")
Lire (T[i].Mn)
Jusqu'à (0 ≤ T[i].Mn) Et (T[i].Mn ≤ 59)
Fin Pour
FIN| Objet | Type / Nature | Rôle |
|---|---|---|
| i | Entier | Compteur de parcours du tableau |
4.a Idée : un ordre sur deux clés se teste ainsi : la clé principale est strictement plus grande, ou elle est égale et la clé secondaire est plus grande. Et un échange déplace l'enregistrement entier. La seule séquence correcte est la séquence b.
4.b Séquence a : le Ou ne vérifie pas l'égalité des heures. Avec T[0] = ("Tunis-Nabeul", 9, 45) et T[1] = ("Gafsa-Tozeur", 14, 30), le test 9 > 14 est faux mais 45 > 30 est vrai : les deux matchs sont échangés. On obtient T[0] = ("Gafsa-Tozeur", 14, 30) et T[1] = ("Tunis-Nabeul", 9, 45) : le match de 14:30 passe avant celui de 9:45.
Séquence c : la condition est juste, mais seuls les champs H et Mn sont échangés. Avec T[0] = ("Sfax-Gabès", 16, 30) et T[1] = ("Tunis-Nabeul", 9, 45), on obtient T[0] = ("Sfax-Gabès", 9, 45) et T[1] = ("Tunis-Nabeul", 16, 30) : les horaires sont rangés, mais chaque libellé porte l'horaire de l'autre match.
4.c Dans la séquence b, x reçoit un enregistrement entier : x est de type Match. Dans la séquence c, x est un entier, ce qui confirme qu'on n'y déplace que des champs.
5. Idée : on généralise la séquence b à deux cases voisines T[i] et T[i + 1] et on la répète dans un tri à bulles, qui s'arrête après un passage sans permutation. Le test d'ordre est confié à une fonction.
Fonction Apres (a, b : Match) : Booléen
DEBUT
Retourner (a.H > b.H) Ou ((a.H = b.H) Et (a.Mn > b.Mn))
FINProcédure Trier (@ T : Tab, N : Entier)
DEBUT
Répéter
permute ← Faux
Pour i de 0 à N - 2 Faire
Si Apres (T[i], T[i + 1]) Alors
x ← T[i]
T[i] ← T[i + 1]
T[i + 1] ← x
permute ← Vrai
Fin Si
Fin Pour
Jusqu'à Non (permute)
FIN| Objet | Type / Nature | Rôle |
|---|---|---|
| i | Entier | Indice de parcours |
| x | Match | Enregistrement auxiliaire de l'échange |
| permute | Booléen | Vrai si un échange a eu lieu pendant le passage |
| Apres | Fonction | Tester si a doit être placé après b |
Une autre solution acceptable compare une seule clé, le nombre de minutes depuis minuit H * 60 + Mn : elle donne le même ordre puisque Mn < 60.
6. Idée : on applique le critère sur les deux champs, sans oublier que deux matchs de même horaire ne sont jamais échangés (test strict). Le tri demande 4 passages, le dernier sans permutation. On obtient :
| i | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Lib | Bizerte-Béja | Tunis-Nabeul | Gafsa-Tozeur | Sousse-Kef | Sfax-Gabès | Monastir-Mahdia |
| H | 9 | 9 | 14 | 16 | 16 | 16 |
| Mn | 5 | 45 | 30 | 0 | 30 | 30 |
Sfax-Gabès et Monastir-Mahdia commencent tous deux à 16:30 : ils gardent leur ordre de départ. Sousse-Kef (16:00) passe avant eux, car à heure égale on compare les minutes.
7. Idée : un match donne une ligne. Un entier inférieur à 10 doit être précédé d'un "0" : on confie ce formatage à une fonction qui retourne une chaîne de deux caractères.
Fonction Deux (x : Entier) : Chaîne
DEBUT
Si x < 10 Alors
Retourner "0" + Convch (x)
Sinon
Retourner Convch (x)
Fin Si
FINProcédure Planning (T : Tab, N : Entier)
DEBUT
Ouvrir ("D:\Planning.txt", F, "w")
Pour i de 0 à N - 1 Faire
ligne ← Deux (T[i].H) + ":" + Deux (T[i].Mn) + " " + T[i].Lib
Ecrire_nl (F, ligne)
Fin Pour
Fermer (F)
FIN| Objet | Type / Nature | Rôle |
|---|---|---|
| F | Fichier texte | Nom logique du fichier "Planning.txt" |
| i | Entier | Indice de parcours |
| ligne | Chaîne | Ligne à écrire |
| Deux | Fonction | Écrire un entier sur deux chiffres |
Pour le tableau trié de la question 6, le fichier "Planning.txt" contient :
09:05 Bizerte-Béja
09:45 Tunis-Nabeul
14:30 Gafsa-Tozeur
16:00 Sousse-Kef
16:30 Sfax-Gabès
16:30 Monastir-Mahdia