Aller au contenu

Un mot pour Fahmio

Tu écris. Tu continues.

Un problème, une idée — assez pour qu’on comprenne, puis tu retournes à ta copie.

On lit. Tu n’as rien d’autre à faire.

Où veux-tu aller ?

↑ ↓ pour parcourir · Entrée pour ouvrir · Échap pour fermer

Fahmio
Fahmio
Bac Tunisie
FE-DFichiers, enregistrements et matrices

Tableau d'enregistrements : déclarer le type, remplir, trier sur deux clés en échangeant l'enregistrement entier

Idée directrice

Des objets à plusieurs caractéristiques (un rendez-vous, un match, une date, un élève) se rangent dans un tableau d'enregistrements : on déclare l'enregistrement puis le tableau, on remplit en contrôlant chaque champ, et on accède aux valeurs par T[i].champ. Pour trier, on compare sur un champ (puis sur un second en cas d'égalité), mais on échange l'enregistrement entier, avec un auxiliaire du type enregistrement : échanger un seul champ défait les enregistrements.

Ce qui aide à reconnaître la démarche

« Chaque … est un enregistrement formé de … champs » ; « Compléter le tableau de déclaration des nouveaux types » ; « trier … dans l'ordre croissant du … et en cas d'égalité … » ; « L'instruction e1 ← e2 … » ; « Donner une structure de données adéquate pour représenter … » ; « donner le type de l'objet x »

Besoin d’un point de départ ? Voir la méthode
  • TDNT : l'enregistrement d'abord (un champ par ligne, avec son type), puis Tab = Tableau de … <enregistrement>. Les bornes des champs se contrôlent à la saisie.
  • Affectation globale e1 ← e2 permise entre enregistrements de même type ; comparaison globale interdite : on compare des champs.
  • Tri sur deux clés : (a.c1 > b.c1) Ou ((a.c1 = b.c1) Et (a.c2 > b.c2)), de préférence dans une fonction booléenne.
  • Échange : x ← T[i] ; T[i] ← T[j] ; T[j] ← x, avec x du type enregistrement.
  • Saisie : une boucle Répéter … Jusqu'à par champ contraint, à l'intérieur de la boucle Pour ; T et N passés par adresse (@).
Les pièges à vérifier dans ta démarche

Échanger le seul champ de la clé : les clés sont rangées mais chaque enregistrement est défait. Écrire le critère à deux clés avec un Ou simple, sans vérifier l'égalité de la clé principale. Comparer deux enregistrements globalement (T[i] > T[i + 1]). Déclarer x de type Entier alors qu'il reçoit un enregistrement. Oublier le test strict, qui garde dans leur ordre les enregistrements de même clé. Pour une date, comparer le jour avant l'année.

Sujet principal

Exercice — tableau d'enregistrements (5 points), dans l'esprit des sessions 2016–2026

7 questionsCorrigé masqué

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 Si
Sé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 Si
Sé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 Si

On donne aussi, pour N = 6, le tableau T suivant :

i012345
LibSfax-GabèsTunis-NabeulSousse-KefBizerte-BéjaGafsa-TozeurMonastir-Mahdia
H1691691416
Mn3045053030

Travail demandé :

  1. 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.
  2. 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.
    1. L'instruction e1 ← e2 recopie la valeur de chacun des trois champs de e2 dans le champ correspondant de e1.
    2. L'instruction e1 ← e2 recopie uniquement le premier champ, Lib.
    3. L'instruction e1 ← e2 est incorrecte : il faut affecter les champs un par un.
    4. L'instruction Si e1 < e2 Alors … compare correctement les horaires de deux matchs.
  3. É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.
  4. Séquences a, b et c données ci-dessus.
    1. Indiquer la seule séquence correcte.
    2. 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.
    3. Donner le type de l'objet x dans la séquence correcte.
  5. É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.
  6. Donner le contenu du tableau T donné ci-dessus après l'appel de Trier(T, 6).
  7. É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 exemple 09: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
ObjetType / NatureRôle
iEntierCompteur 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))
FIN
Procé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
ObjetType / NatureRôle
iEntierIndice de parcours
xMatchEnregistrement auxiliaire de l'échange
permuteBooléenVrai si un échange a eu lieu pendant le passage
ApresFonctionTester 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 :

i012345
LibBizerte-BéjaTunis-NabeulGafsa-TozeurSousse-KefSfax-GabèsMonastir-Mahdia
H9914161616
Mn5453003030

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
FIN
Procé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
ObjetType / NatureRôle
FFichier texteNom logique du fichier "Planning.txt"
iEntierIndice de parcours
ligneChaîneLigne à écrire
DeuxFonctionÉ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

Changer d’énoncé, garder le raisonnement

Choisis un seul transfert après le sujet principal. Qu’est-ce qui change ? Quel résultat ou quelle méthode peux-tu réutiliser ? Les autres exercices restent disponibles pour une prochaine séance.

Variantes rencontrées : structure Date à proposer puis tri croissant des dates de naissance (contrôle 2016) ; enregistrements imbriqués Eleve/Date et valeurs hors domaine (principale 2016) ; tableaux d'enregistrements Personne triés sur un champ, recopiés dans un troisième tableau (contrôle 2017) ; déclaration d'un enregistrement, affectation globale et choix de la bonne séquence d'échange (principale 2021) ; rendez-vous triés sur le mois puis le jour (contrôle 2021) ; tableau d'enregistrements rempli par un générateur (contrôle 2021, principale 2021) ; tableau d'enregistrements rempli depuis un fichier texte ou une matrice (contrôle et principale 2026) ; fichier d'enregistrements trié vers un fichier texte (principale 2026).

Exercices d'entraînement — une nuance à la fois

1 Drill FE-D.1 — enregistrement imbriqué dans un fichier : un champ de type Date dans l'enregistrement Eleve
Entraînement 01 / 01

Drill FE-D.1 — enregistrement imbriqué dans un fichier : un champ de type Date dans l'enregistrement Eleve

5 questionsCorrigé masqué

On donne le tableau de déclaration des nouveaux types suivant :

Date = Enregistrement
    J : Entier
    M : Entier
    A : Entier
Fin
Eleve = Enregistrement
    Nom : Chaîne
    Moy : Réel
    DN : Date
Fin
FEleves = Fichier de Eleve

Le fichier d'enregistrements "Eleves.dat", de type FEleves, enregistré dans le dossier D:\Classe, contient au moins un élève. Les élèves de cette classe sont nés entre 2005 et 2010, et une moyenne est comprise entre 0 et 20. Un élève est noté (nom ; moyenne ; date de naissance).

Travail demandé :

  1. Pour chacun des élèves suivants, écrire V s'il peut être enregistré dans "Eleves.dat" sans anomalie, ou F dans le cas contraire en justifiant la réponse :
    1. ("Yasmine" ; 16,5 ; 12/07/2008)
    2. ("Karim" ; 21 ; 03/05/2007)
    3. ("Nour" ; 13 ; 31/13/2008)
    4. ("Omar" ; 11,25 ; 15/02/2011)
  2. Soit e une variable de type Eleve. Écrire les instructions qui :
    1. affichent le mois de naissance de l'élève e ;
    2. affectent à l'élève e la date de naissance 01/09/2008.
  3. Écrire l'algorithme d'une fonction NesEn(chemin, m) qui retourne le nombre d'élèves du fichier dont le chemin est chemin qui sont nés au mois m.
  4. Écrire l'algorithme d'une fonction Major(chemin) qui retourne le nom du premier élève du fichier ayant la plus forte moyenne, en un seul parcours du fichier.
  5. Le fichier "Eleves.dat" contient, dans cet ordre, les élèves ("Yasmine" ; 16,5 ; 12/07/2008), ("Fedi" ; 12 ; 03/03/2008), ("Aya" ; 14,25 ; 28/03/2007), ("Selim" ; 9,5 ; 17/11/2008), ("Maha" ; 15 ; 09/03/2008). Donner la valeur de NesEn("D:\Classe\Eleves.dat", 3) et celle de Major("D:\Classe\Eleves.dat").
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : on contrôle chaque champ, y compris ceux de la date imbriquée : moyenne de 0 à 20, jour de 1 à 31, mois de 1 à 12, année de 2005 à 2010.

ÉlèveV/FJustification
("Yasmine" ; 16,5 ; 12/07/2008)VTous les champs sont dans leur domaine
("Karim" ; 21 ; 03/05/2007)FLa moyenne 21 dépasse 20
("Nour" ; 13 ; 31/13/2008)FLe mois 13 n'existe pas
("Omar" ; 11,25 ; 15/02/2011)FL'année 2011 est hors de 2005..2010

2. Idée : on descend d'un niveau par point : e.DN est une Date, e.DN.M un entier.

Ecrire (e.DN.M)
e.DN.J ← 1
e.DN.M ← 9
e.DN.A ← 2008

Autre solution pour la seconde instruction : remplir une variable d de type Date, puis écrire e.DN ← d, affectation globale entre deux enregistrements de même type.

3. Idée : on ouvre le fichier en lecture binaire, on lit les enregistrements un par un jusqu'à la fin, et on teste le champ M du champ DN de chaque enregistrement lu.

Fonction NesEn (chemin : Chaîne, m : Entier) : Entier
DEBUT
    Ouvrir (chemin, F, "rb")
    nb ← 0
    Tant que Non (Fin_fichier (F)) Faire
        Lire (F, e)
        Si e.DN.M = m Alors
            nb ← nb + 1
        Fin Si
    Fin Tant que
    Fermer (F)
    Retourner nb
FIN
ObjetType / NatureRôle
FFElevesNom logique du fichier des élèves
eEleveEnregistrement lu
nbEntierNombre d'élèves nés au mois m

4. Idée : le premier enregistrement lu sert de meilleur provisoire ; ensuite, seule une moyenne strictement plus grande le remplace, ce qui garde le premier élève en cas d'égalité. On retient le nom au moment où la moyenne est lue : il n'y a pas à revenir dans le fichier pour le retrouver.

Fonction Major (chemin : Chaîne) : Chaîne
DEBUT
    Ouvrir (chemin, F, "rb")
    Lire (F, e)
    best ← e.Moy
    nom ← e.Nom
    Tant que Non (Fin_fichier (F)) Faire
        Lire (F, e)
        Si e.Moy > best Alors
            best ← e.Moy
            nom ← e.Nom
        Fin Si
    Fin Tant que
    Fermer (F)
    Retourner nom
FIN
ObjetType / NatureRôle
FFElevesNom logique du fichier des élèves
eEleveEnregistrement lu
bestRéelPlus forte moyenne rencontrée
nomChaîneNom de l'élève correspondant

5. Fedi (03/03), Aya (28/03) et Maha (09/03) sont nés en mars : NesEn renvoie 3. La plus forte moyenne est 16,5 : Major renvoie "Yasmine".

Relier ce raisonnement au bac

Choisis une filière pour voir les sujets qui étayent ce scénario.