• Aucun résultat trouvé

Un dernier exemple : la fréquence des lettres d'un texte

F N Pour C allant de N-1 Ô 1 F F * C F ← N Pour C allant de N-1 Ô 2 F F * C

7. Un dernier exemple : la fréquence des lettres d'un texte

Il va s'agir ici de fournir la fréquence des diverses lettres minuscules présentes dans un texte fourni par l'utilisateur.

7.1 Quoi faire

Voici, comme d'habitude des exemples des affichages souhaités :

Comme d'habitude, nous allons profiter de cet exemple pour introduire une possibilité technique supplémentaire : la saisie par l'exécutant d'un seul caractère frappé par l'utilisateur au clavier (sans attendre l'appui sur la touche Entrée) et sans que le caractère ainsi lu ne soit répercuté à l'écran.

7.2 Une information supplémentaire

Nous savons déjà qu'un texte peut être fourni au clavier par l'utilisateur, puis saisi par l'exécutant au moment de l'appui sur la touche Entrée, pour être placé dans une variable de type string. C'est l'instruction readln qui permet une telle lecture.

Ce type d'instruction de lecture présente pour l'utilisateur l'avantage que, tant qu'il n'a pas frappé la touche Entrée, il peut corriger le texte en supprimant les derniers caractères frappés grâce à la touche BackSpace. Le problème tient à la taille du texte qu'on peut ainsi faire lire puisque les variables string ne peuvent contenir qu'au plus 255 caractères. Mais, en tous cas, le texte tout entier est présent dans la variable string où il est déposé à l'issue de l'instruction de lecture.

Un autre type de lecture de caractères est possible : cette fois, chaque caractère sera saisi "au vol" par l'exécutant, sans d'ailleurs que le caractère pressé par l'utilisateur ne soit répercuté à l'écran.

C'est une fonction de type char et sans argument qui va offrir cette possibilité : la fonction readkey qui contient le dernier caractère frappé par l'utilisateur.

Cette manière de faire présente un net désavantage pour l'utilisateur : chaque caractère frappé est saisi (et traité) et il est trop tard pour corriger ou revenir en arrière. Il faut bien voir également que si tout un texte frappé doit être globalement présent en mémoire, ce sera au programmeur de commander les traitements nécessaires pour que l'ensemble des caractères restent présents dans une variable ou un tableau ad-hoc.

Ce sera au programmeur aussi de prévoir comment la fin du texte (=la fin des frappes successives des caractères) sera signalée.

C'est cette possibilité que nous allons utiliser ici : le texte sera saisi, caractère par caractère, jusqu'à la frappe du caractère $. Les fréquences des minuscules apparues dans la succession seront ensuite affichées.

7.3 Retour au "quoi faire ?" 7.3.1 En ce qui concerne les entrées

L'utilisateur fournira donc une suite de caractères, sans possibilité de retour en arrière; chaque caractère saisi est traité immédiatement. Ces caractères peuvent être quelconques et en nombre quelconque. La fin du texte sera marquée par la frappe du caractère $ qui interrompra donc le processus des lectures successives des caractères.

Tout ce traitement pourra être repris à la demande de l'utilisateur avec un autre texte.

7.3.2 En ce qui concerne les traitements

Seules les lettres minuscules non accentuées doivent être prises en compte.

7.3.3 En ce qui concerne les sorties

On notera que seule la fréquence des minuscules présentes dans le texte est affichée.

7.4 Comment faire

Pour venir à bout de la tâche demandée, il faut d'abord bien remarquer qu'il n'est absolument pas nécessaire de garder tous les caractères fournis en mémoire : on ne retient chaque caractère que le temps de vérifier si c'est une minuscule et le cas échéant d'ajuster sa fréquence, puis c'est le caractère suivant qui prend sa place.

Mais avant de commencer, on va inscrire la succession des minuscules :

a b c d e f g h i j k l m n o p q r s t u v w x y z pour pouvoir noter (en plaçant une barre sous la lettre correspondante) l'apparition d'une nouvelle minuscule à compter. Ensuite les actions seront les suivantes :

- on accepte un caractère, et tant qu'il ne s'agit pas de $ :

- si ce caractère est une minuscule, on place un trait supplémentaire sous la lettre correspondante;

- ces lectures achevées, on passe en revue les diverses lettres en donnant le nombre de traits relatifs à chaque lettre (comportant au moins un trait);

- on reprend éventuellement le tout en n'oubliant pas, à chaque fois, de bien effacer tous les traits.

7.5 Comment faire faire

Il est évident qu'un tableau sera nécessaire :

Frequence

a b c d e f g h i j k l m n o p q r s t u v w x y z

En Pascal, il se décrira :

Nous sommes en mesure de proposer une marche à suivre, en faisant apparaître au fur et à mesure, à droite, les variables nécessaires. Cette fois, nous ne la proposerons plus sous forme GNS, mais seulement en utilisant le langage de description d'algorithmes.

Répéter

Pour Compteur allant de 'a' à 'z' Compteur, de type char Frequence[Compteur] ← 0

Caractere ← readkey (1) Caractere, de type char

Affiche (sans passage à la ligne) Caractere (2)

Tant que Caractère ≠ '$'

Si (Caractere 'a') et (Caractere ≤ 'z') alors

Frequence[Caractere] Frequence[Caractere] + 1

Caractere ← readkey (1)

Affiche (sans passage à la ligne) Caractere (2)

Pour Compteur allant de 'a' à 'z'

Si Frequence[Compteur] ≠ 0 alors

Affiche (Compteur,' est ',Frequence[Compteur],' fois dans le texte') Affiche('Voulez-vous recommencer avec un autre texte oui ou non ? ')

Lis et place dans Reponse Reponse de type string

jusqu'à ce que (Reponse='non') ou (Reponse='NON');

7.6 Comment dire

Et voici le programme résultant, correctement "habillé" : program FREQLETTRE;

(* Ce programme fait lire un texte caractère par caractère jusqu'à la donnée d'un caractère de fin et fait afficher pour chacune des lettres minuscules présente dans le texte sa fréquence.

Les caractères accentués ne seront pas pris en compte.

Tout le processus pourra être répété, à la demande avec un nouveau texte *)

uses WinCRT;

var Frequence : array['a'..'z'] of integer; (* pour stocker les fréquences des minuscules *)

Caractere, (* qui contiendra successivement les divers caractères du texte *)

Compteur (* pour accéder aux composantes successives de Frequence *)

: char;

Reponse (* pour savoir si l'utilisateur veut reprendre le tout *)

: string[3]; begin

(* avertissement de l'utilisateur *)

clrscr; (* pour l'effacement de l'écran *)

writeln('Vous allez me fournir un texte (sans possibilité de corriger.'); writeln('les fautes de frappe éventuelles) et en marquant la fin par la'); writeln('frappe du caractère $.');

writeln('Je vous donnerai alors la fréquence de toutes les minuscules '); writeln('non accentuées que vous aurez frappées au sein de votre texte.'); writeln('Tout le travail pourra être repris à votre demande avec un texte'); writeln('différent.');

writeln; (* pour passer une ligne *)

repeat

(* initialisation du tableau Frequence *)

for Compteur := 'a' to 'z' do Frequence[Compteur] := 0;

(* Lecture du texte caractère par caractère *)

writeln('Donnez le texte : ');

Caractere := readkey; (1)

write(Caractere); (2)

while Caractere <>'$' do begin

if (Caractere>='a') and (Caractere<='z') then Frequence[Caractere]:=Frequence[Caractere]+1;

write(Caractere); (2)

end;

(* Affichage *)

clrscr; (* pour l'effacement de l'écran *)

writeln('FREQUENCE DES MINUSCULES DANS LE TEXTE'); writeln('======================================');

for Compteur := 'a' to 'z' do

if Frequence[Compteur] <> 0 then

writeln(Compteur,' est ',Frequence[Compteur],' fois dans le texte'); writeln;

write('Voulez-vous recommencer avec un autre texte oui ou non ? '); readln(Reponse);

until (Reponse='non')or(Reponse='NON'); end.

(1) readkey est une fonction de type caractère (char) qui fournit le dernier caractère frappé au clavier; comme readkey désigne un caractère, il faut bien saisir que

readkey

employé seul ne constitue pas une instruction correcte, pas plus que succ(Compteur)

ou

Caractere

Il faut indiquer ce qui doit être fait de la donnée désignée par readkey : ici on la fait placer dans la variable Caractere.

(2) J'ai signalé que lorsque readkey est utilisé pour saisir le caractère frappé par l'utilisateur, ce caractère n'a pas d'écho à l'écran; si donc je veux que les caractères frappés par l'utilisateur apparaissent à l'écran, à chaque fois immédiatement après qu'ils soient saisis par readkey, il me faut les faire afficher; comme chaque caractère lu est déposé dans Caractere, il suffit de demander l'affichage (sans passage à la ligne) de Caractere.