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
SD-EStructures de données et modularité

Problème modulaire — club de lecture (tableaux de chaînes, inactifs, recherche)

Idée directrice

Forme calquée sur le problème 2018 (session principale) : un contexte applicatif (groupe / club), deux tableaux de chaînes liés par un indice d'émetteur, contrôles de saisie, puis affichages dépendants (inactifs + recherche d'un commentaire). L'attendu principal n'est pas un mini-exercice isolé : c'est l'analyse modulaire (programme principal, TDNT, TDOG) puis les algorithmes de chaque module avec TDOL.

Ce qui aide à reconnaître la démarche

« Analyser le problème en le décomposant en modules » ; « Écrire les algorithmes et les tableaux de déclaration (TDNT/TDOG/TDOL) » ; « contrôles de saisie » ; « tableaux de chaînes »

Besoin d’un point de départ ? Voir la méthode
  • Commencer par l'analyse (Nom, flux des appels, résultats) avant d'écrire une ligne d'algorithme.
  • TDNT pour les types tableaux ; TDOG pour objets globaux + modules ; TDOL par module.
  • Les contrôles de saisie (Répéter / Jusqu'à … dans […]) sont notés dans le barème du problème 2018.
  • Inactifs et Recherche ne se comprennent qu'après RemplirA / RemplirM : ne pas les traiter comme des exercices isolés.
Les pièges à vérifier dans ta démarche

Oublier l'unicité des noms ; écrire M[i] ← message sans le préfixe NumE# ; confondre l'indice dans A avec le rang dans M ; afficher les inactifs avant d'avoir rempli Occ.

Sujet principal

Problème — gestion d'un club de lecture

7 questionsCorrigé masqué

Un club de lecture souhaite gérer les discussions de ses adhérents. On se propose d'écrire un programme permettant d'afficher à l'administrateur :

  • la liste des adhérents inactifs (aucun commentaire envoyé) ;
  • la liste des adhérents qui ont envoyé un même commentaire donné.

Pour cela, le programme doit :

  • Remplir un tableau A par les noms d'utilisateurs des na adhérents, avec 5≤na≤505 \le na \le 50. Un nom est une chaîne de caractères unique, de longueur ≥3\ge 3, commençant par une lettre majuscule.
  • Remplir un tableau M par les nm commentaires (3≤nm≤1003 \le nm \le 100) au format NumE#texte, où NumE est l'indice de l'émetteur dans A et texte est le message. On tiendra aussi un tableau d'entiers Occ : nombre de messages par adhérent.
  • Afficher les adhérents inactifs (Occ[i] = 0), puis, après saisie d'un commentaire, afficher les émetteurs correspondants (extraction de la sous-chaîne après # et lecture de l'indice avant #).

Exemple. Pour na = 5, nm = 5, A = ["Lina", "Omar", "Sami", "Ines", "Noura"] et M = ["1#Bonjour", "3#Algo", "1#Bonjour", "2#Relecture", "3#Bonjour"] : le commentaire "Bonjour" est envoyé par Lina et Sami (chaque nom est affiché une seule fois) ; les adhérents inactifs sont Ines et Noura.

Travail demandé :

  1. Analyser le problème en le décomposant en modules (procédures / paramètres : remplissage de A, remplissage de M et de Occ, affichage des inactifs, recherche des émetteurs d'un commentaire).
  2. Écrire les algorithmes et les tableaux de déclaration des objets relatifs aux modules envisagés (TDNT, TDOG, TDOL). Les contrôles de saisie doivent apparaître explicitement.
Voir la correction commentéeAprès avoir posé votre démarche

1. Analyse du programme principal

Nom : ClubLecture
  A, na = PROC RemplirA(A, na)
  M, nm, Occ = PROC RemplirM(A, M, Occ, na, nm)
  PROC Inactifs(Occ, A, na)
  PROC Recherche(M, A, na, nm)
Fin ClubLecture

TDNT

Tab1 = Tableau [1..100] de chaîne de caractères
Tab2 = Tableau [1..100] d'entiers
TabBool = Tableau [1..100] de booléens

TDOG

  • A : Tab1 — noms des adhérents
  • M : Tab1 — messages au format NumE#texte
  • Occ : Tab2 — nombre de messages par adhérent
  • na, nm : entiers — effectifs
  • RemplirA, RemplirM, Inactifs, Recherche : procédures

2. Algorithmes des modules

a) RemplirA — saisie contrôlée des noms.

DEF PROC RemplirA(var A:Tab1 ; var na:entier)
1) Répéter
     Écrire("Donner le nombre d’adhérents :")
     Lire(na)
   Jusqu’à (na dans [5..50])
2) Pour i de 1 à na faire
     Répéter
       Écrire("Nom de l’adhérent n°", i, " : ")
       Lire(A[i])
       valide ← Faux
       Si Long(A[i]) ≥ 3 alors
         valide ← (A[i][1] dans ["A".."Z"])
       FinSi
       Si valide alors valide ← NON Existe(A[i], A, i-1) FinSi
     Jusqu’à valide
   FinPour
3) Fin RemplirA

TDOL : i entier (compteur) ; valide booléen (validité du nom saisi) ; Existe fonction (unicité dans le préfixe de A).

0) DEF FN Existe(ch:chaîne ; t:Tab1 ; indice:entier):booléen
1) i ← 1 ; trouve ← Faux
2) TantQue (i ≤ indice) ET (NON trouve) faire
     Si t[i] = ch alors trouve ← Vrai FinSi
     i ← i+1
   FinTantQue
3) Existe ← trouve
4) Fin Existe

TDOL d’Existe : i, entier, position testée ; trouve, booléen, présence de la chaîne dans le préfixe. Pour indice=0, aucune case du tableau n’est lue et la fonction retourne Faux.

b) RemplirM — commentaires + comptage.

DEF PROC RemplirM(A:Tab1 ; var M:Tab1 ; var Occ:Tab2 ; na:entier ; var nm:entier)
1) Répéter
     Écrire("Donner le nombre de commentaires :")
     Lire(nm)
   Jusqu'à (nm dans [3..100])
2) Pour i de 1 à na faire Occ[i] ← 0 FinPour
3) Pour i de 1 à nm faire
     Écrire("Donner le commentaire :") ; Lire(message)
     Répéter
       Écrire("Donner le numéro de l'émetteur :") ; Lire(NumE)
     Jusqu'à (NumE dans [1..na])
     Convch(NumE, ch)
     M[i] ← Concat(Concat(ch, "#"), message)
     Occ[NumE] ← Occ[NumE] + 1
   FinPour
4) Fin RemplirM

TDOL : NumE, i entiers ; message, ch chaînes.

c) Inactifs — dépend de Occ produit par RemplirM.

DEF PROC Inactifs(Occ:Tab2 ; A:Tab1 ; na:entier)
1) Écrire("Adhérents inactifs :")
2) Pour i de 1 à na faire
     Si Occ[i] = 0 alors Écrire(A[i]) FinSi
   FinPour
3) Fin Inactifs

d) Recherche — dépend de M et A ; dernière question du problème.

DEF PROC Recherche(M,A:Tab1 ; na,nm:entier)
1) Écrire("Commentaire à chercher :") ; Lire(msg)
2) Pour i de 1 à na faire dejaAffiche[i] ← Faux FinPour
3) Pour i de 1 à nm faire
     Si Sous-chaine(M[i], Pos("#",M[i])+1, Long(M[i])-Pos("#",M[i])) = msg alors
       Valeur(Sous-chaine(M[i],1,Pos("#",M[i])-1), Nume, e)
       Si NON dejaAffiche[Nume] alors
         Écrire(A[Nume])
         dejaAffiche[Nume] ← Vrai
       FinSi
     FinSi
   FinPour
4) Fin Recherche

TDOL : i, Nume, e entiers ; msg chaîne. dejaAffiche : TabBool, indique pour chaque adhérent s’il a déjà été affiché lors de cette recherche.

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.

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

1 Retirer les messages sans casser les indices des adhérents
Entraînement 01 / 01

Retirer les messages sans casser les indices des adhérents

2 questionsCorrigé masquéEn cours de relecture

Un club conserve les noms de cinq adhérents dans A = ["Lina", "Omar", "Sami", "Ines", "Noura"]. Le tableau M contient nm commentaires sous forme de chaînes indice#texte, où l’indice désigne une case de A. Les indices commencent à 1. Le texte peut contenir # : seul le premier séparateur termine l’indice. Les données sont déjà valides. Occ[i] contient le nombre de commentaires de l’adhérent i.

Initialement nm = 6, M = ["2#Aide", "1#Question", "2#Merci", "5#Plan", "3#Exemple", "2#Suite"] et Occ = [1,3,1,0,1]. On veut supprimer tous les commentaires d’un adhérent a, sans changer les indices dans A, et conserver l’ordre des autres commentaires.

  1. Donner les types de tableaux nécessaires et le TDOL d’une procédure Retirer. Écrire son algorithme avec ses paramètres et modes de passage. Le tableau M a une capacité de 100 ; nm peut devenir nul ; seule sa zone 1..nm est utilisée.
  2. Donner la trace des positions de lecture/écriture pour a = 2, puis le nouveau M utile, nm et Occ. Expliquer pourquoi compacter également A serait incorrect sans autre traitement.

Cet exercice et sa correction sont en cours de relecture. Tu peux les consulter ; l’exercice n’est pas encore proposé en séance.

Voir la correction commentéeAprès avoir posé votre démarche

Types et contrat. TabCh = Tableau [1..100] de chaînes ; TabEnt = Tableau [1..100] d’entiers. M, nm et Occ sont des paramètres modifiés (var) ; a est un entier d’entrée dans [1..5]. A reste inchangé. TDOL : i entier (rang lu), k entier (dernier rang conservé), auteur entier (indice extrait), posSep entier (premier séparateur), e entier (code de conversion).

0) DEF PROC Retirer(var M:TabCh ; var nm:entier ; var Occ:TabEnt ; a:entier)
1) k ← 0
2) Pour i de 1 à nm faire
     posSep ← Pos("#",M[i])
     Valeur(Sous-chaine(M[i],1,posSep-1),auteur,e)
     Si auteur ≠ a alors
       k ← k+1
       M[k] ← M[i]
     FinSi
   FinPour
3) nm ← k
4) Occ[a] ← 0
5) Fin Retirer

Trace. Pour i = 1,2,3,4,5,6, l’auteur lu vaut respectivement 2,1,2,5,3,2 et k après traitement vaut 0,1,1,2,3,3. La zone utile finale est ["1#Question", "5#Plan", "3#Exemple"], nm = 3 et Occ = [1,0,1,0,1]. Les cases au-delà de nm sont ignorées. Comme k ≤ i, une écriture n’écrase jamais un commentaire pas encore lu. Si tous les messages appartiennent à a, k reste nul : le tableau utile est vide.

Dépendance entre tableaux. Les indices contenus dans M renvoient toujours à A. Supprimer A[2] déplacerait par exemple Noura du rang 5 au rang 4, alors que "5#Plan" garderait son ancien indice. On conserve donc les adhérents, même sans commentaires. Les compteurs des autres adhérents ne changent pas puisque leurs messages sont conservés.

Relier ce raisonnement au bac

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