Problème — gestion d'un club de lecture
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
Apar les noms d'utilisateurs desnaadhérents, avec . Un nom est une chaîne de caractères unique, de longueur , commençant par une lettre majuscule. - Remplir un tableau
Mpar lesnmcommentaires () au formatNumE#texte, oùNumEest l'indice de l'émetteur dansAettexteest le message. On tiendra aussi un tableau d'entiersOcc: 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é :
- Analyser le problème en le décomposant en modules (procédures / paramètres : remplissage de
A, remplissage deMet deOcc, affichage des inactifs, recherche des émetteurs d'un commentaire). - É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 ClubLectureTDNT
Tab1 = Tableau [1..100] de chaîne de caractères
Tab2 = Tableau [1..100] d'entiers
TabBool = Tableau [1..100] de booléensTDOG
A: Tab1 — noms des adhérentsM: Tab1 — messages au formatNumE#texteOcc: Tab2 — nombre de messages par adhérentna,nm: entiers — effectifsRemplirA,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 RemplirATDOL : 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 ExisteTDOL 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 RemplirMTDOL : 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 Inactifsd) 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 RechercheTDOL : 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.