cs_architect
Messages postés6Date d'inscriptionsamedi 29 janvier 2005StatutMembreDernière intervention12 février 2005
-
30 janv. 2005 à 20:58
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 2008
-
2 févr. 2005 à 13:43
Bonjour,
Je suis tout nouveau et surtout tout débutant sous delphi.
J'ai une question qui me tracasse et que je ne trouve pas sur le net :
Imaginons que l'on tape une chaîne de caractères dans un Edit.
J'aimerais pouvoir écrire une fonction qui renvoie
le nombre d'occurences de la lettre la plus présente dans cet Edit,
sans distinction majuscule/minuscule.
Pour cela je cliques sur le bouton OK, qui va m'écrire dans un label le nombre d'occurence.
Et à la limite en ignorant les accents, mais ceci est un extra.
Je sais que cela peut paraître complexe mais je suis très intérréssé par cela.
Merci d'@vance !
A voir également:
Nombre d'occurence algorithme
Algorithme nombre d'occurence dans une chaine - Meilleures réponses
Algorithme nombre d'occurence dans un tableau - Meilleures réponses
ni69
Messages postés1418Date d'inscriptionsamedi 12 juin 2004StatutMembreDernière intervention 5 juillet 201012 Modifié le 15 nov. 2019 à 18:50
Tu peux faire comme ceci :
procedure
TForm1.Button1Click(Sender: TObject);
var
str : string;
count, nbtotal : integer;
begin
nbtotal := 0; // On initialise le nombre de lettres
str := LowerCase(Edit1.Text); // On met toute la chaîne en minuscules
for count : = 1to Length(str) do // On parcours toute la chaîne...
if str[count] = 'e' then inc(nbtotal); // Ici, on cherche les "e"
Label1.Caption : = IntToStr(nbtotal); // Puis, on affiche le nombre de "e" trouvés
end;
@+
Bonne Prog'
Nico
<HR>
N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !
ni69
Messages postés1418Date d'inscriptionsamedi 12 juin 2004StatutMembreDernière intervention 5 juillet 201012 Modifié le 15 nov. 2019 à 18:49
Je complète mon code...
Pour une meilleure compatibilité, tu peux remplacer "LowerCase" par "AnsiLowerCase".
Pour les accents, comme l'a utilisé GrandVizir dans sa source "Des Chiffres Et Des Lettres", tu peux utiliser une table de conversion pour les supprimer lors du test... Merci à lui pour cette idée !
TAccentTbl = record
_From : string;
_Dest : char;
end;
var
str : string;
const MaxAccentTable = 7;
AccentTable : array[0..MaxAccentTable] of TAccentTbl =
( (_From : 'àäâã' ; _Dest : 'a' ),
(_From : 'ç' ; _Dest : 'c' ),
(_From : 'éèêë' ; _Dest : 'e' ),
(_From : 'ìïî' ; _Dest : 'i' ),
(_From : 'ñ' ; _Dest : 'n' ),
(_From : 'ôöò' ; _Dest : 'o' ),
(_From : 'ûüù' ; _Dest : 'u' ),
(_From : 'ÿ' ; _Dest : 'y' )
);
IMPLEMENTATION
function NoAccents(S:string):string;
//ENLEVE LES ACCENTS D'UNE CHAÎNE EN MINUSCULES
var x, i : integer;
begin
S: =AnsiLowerCase(S);
//L'idée est le parcours de la table de conversion
for x:= 1 to Length(S) do
for i: =0 to MaxAccentTable do
if Pos(S[x],AccentTable[i]._From)<>0 then
S[x]:= AccentTable[i]._Dest; //si accentué, alors on remplace par le caractère non accentué
str:=S;
end ;
procedure
TForm1.Button1Click(Sender: TObject);
var count, nbtotal : integer;
begin
nbtotal : = 0;
str := AnsiLowerCase(Edit1.Text); // On convertit la chaîne en minuscules
NoAccents(str); // Enlève les accents avec la méthode de GrandVizir
for count : = 1 to Length(str) do
if str[count] = 'e' then inc(nbtotal); // On teste la présence du "e"
Label1.Caption : = IntToStr(nbtotal); // On affiche le nombre d'occurences trouvées
end
Voilà... J'espère que cela te conviendra !
@+
Bonne Prog'
Nico
N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !
cs_sim51
Messages postés240Date d'inscriptiondimanche 31 octobre 2004StatutMembreDernière intervention31 décembre 20062 31 janv. 2005 à 14:29
Je suis d'accord avec toi ni69, cependant il recherche la lettre qui
revient le plus souvent dans un pot et donc pas forcement le 'e'.
Donc architect à toi de modifier cette source.
Soit tu fais le même principe en répétant cette source pour
toutes les lettres de l'alphabet : tu créer un tableau à 2 dimensions
avec toutes les les lettres de l'alphabet et le nombre d'occurence et
au lieu de mettre if str[count] = 'e' tu mets
if str[count] = alphabet[i] avec une boucle for i:=1 to 26 tu aura ton résultat en cherchent le max dans le tableau
Ou alors au lieu de créer le tableau de tout l'alphabet, tu le fais à
partir des lettres du Tedit ( je t'envoie dans l'aide de delphi pour
voir la fonction copy sur une chane de caractère ) et idem ta réponse
se fera par la recherche du max dans ton tableau
N'oubliez pas de cliquer sur réponse acceptée si la réponse vous convient !!!
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 20082 Modifié le 15 nov. 2019 à 18:57
Hi,
Je raisonnerais plutot comme sim51 à une petite différence près: je
cree un Counts: array [Char] of Integer initialisé à 0, le mets la
chaine en minuscules (ou en maj), puis je parcours la chaine caractere
par caractere.
Comme cela j'incrémente Counts[S[c]] à chaque caractère parcouru (c, comme var de controle, S étant la chaine)
Après on cherche le plus gros nombre en parcourant le tableau et on renvoie le résultat.
Ce qui donne
procedure OccurenceLettrePlusPresente(S: string; var Lettre: Char; var Nbre: Integer);
var
i: Integer;
C, Max: Char;
Occurences: array [Char] of Integer;
begin
FillChar(Occurences,SizeOf(Occurences),0); // On initialise tout à zéro
S:=AnsiUpperCase(S); // Pour ignorer la casse.
for i:=1 to Length(S) do
begin
Inc(Occurences[S[i]]); // On incrémente.
end;
Max:=#0;
for C:=Low(Char) to High(Char) do
if Occurences[C] > Occurences[Max] then
Max:=C;
Lettre:=Max;
Nbre:=Occurences[Max];
end;
Et l'on utilise la procedure comme cela: (dans l'évenement OnClick d'un Bouton)
procedure TForm1.Button1Click(Sender: TObject);
var
Lettre: Char;
Nbre: Integer;
begin
{ Le texte est place dans l'Edit1 et le résultat s'affichera dans le Label1 }
OccurenceLettrePlusPresente(Edit1.Text,Lettre,Nbre);
Label1.Caption:=Format('La lettre la plus présente est le "%s" avec %d itérations',[Lettre,Nbre]);
end;
Et voila ...
@ +++ Florent
Si tu ne te plantes pas ......
tu ne poussera jamais
cs_architect
Messages postés6Date d'inscriptionsamedi 29 janvier 2005StatutMembreDernière intervention12 février 2005 Modifié le 15 nov. 2019 à 18:51
Bonjour,
Je vous remercie pour votre rapidité mais il y'a quelque chose que je ne comprend pas dans les réponses.
Et c'est promis, je ferais un "réponse acceptée" dés que je serais chez moi, c'est à dire le week-end.
Tout d'abord pour les première solutions, crée un tableau avec les lettres de l'alphabet, coment faut-il que je me démerde exactement
Faire une variable de ce genre : Alphabet: Array[a, b, c...] of string; et que je le mette dans la variable général (avec le Form1: TForm1;) ?
Ensuite je n'ai pas compris comment est-ce que la fontion ci-dessous peut arriver à compter le nombre de caractère, les reconnaitres, incrémentation, etc.
Pourriez-vous m'expliquer un peu s'il vous plait
for i:=1 to Length(S) do
begin
Inc(Occurences[S[i]]); // On incrémente.
end;
Et quelle est selon vous la meilleur solution, la 1ere ou la 2nd
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 20082 Modifié le 15 nov. 2019 à 18:55
Hello,
Alors en ce qui concerne le tableau, c'est vrai que cela n'est pas une syntaxe que l'on a l'habitude de voir.
Pour creer un tableau de toutes les lettres de l'alphabet, il faut
déclarer un type puis une variable localement (c-à-d dans une
procedure).
Regardes plutot:
procedure TForm1.FormCreate(Sender: TObject);
type
TLettresAlphabet = array['A'..'Z'] of Integer; // Un tableau d'entier représentant les lettres
var
Caracteres: TLettresAlphabet; // La variable en elle même
begin
// ici tu en fait ce que tu veux
end;
Evidemment, tu crees ton type dans la procedure ou tu en as besoin. ;-)
Mon array[Char] of
Integer reprend le même principe sauf qu'il inclue toutes les lettres
disponibles (barres obliques, retour à la ligne, accents ...) Enfin
bref, tout ce qu'une variable de type Char peut recevoir.
Mais, pour ton utilisation, array['A'..'Z'] of Integer serait mieux que array[Char] of Integer car on ne perd pas de place pour ce que l'on a pas besoin.
Après pour le bout de code que tu as recopié, son fonctionnement est très simple.
Occurences étant un array['A'..'Z'] of Integer (c'est mieux ainsi), les numéros des cases ne sont pas des nombres comme pour un array[0..10] of Integer mais des ... Char !!
En gros, une case s'identifie par un caractère compris entre a et z.
Après il faut savoir que si S est une chaine ( string ), alors S[n] correspond au nieme caractere de cette chaine, le premier étant 1, le dernier étant Length(S).
Donc, avec cette boucle for, on
a successivement chaque caractere de la chaine. Comme les cases du
tableau sont identifiées par un caractère, on a accès à la case qui
correspond à la lettre en cours !!! Et comme cela, on incrémente le
nombre d'occurences de cette lettre.
Magique non ????
Donc, à la fiin de cette boucle, on a dans le tableau le nombre d'occurences de chaque lettre dans la chaine.
Il suffit de repassser en vue ce tableau pour trouver le nombre le plus grand.
Sauf que vu que les cases sont identifiées par un Char, il faut que la variable de controle soit ... un Char !!
Avec ces changements au niveau de la structure du tableau, voila la procedure modifiée :
procedure OccurenceLettrePlusPresente(S: string; var Lettre: Char; var Nbre: Integer);
var
i: Integer;
C, Max: Char;
Occurences: array ['A'..'Z'] of Integer;
begin
FillChar(Occurences,SizeOf(Occurences),0); // On initialise tout à zéro
S:=AnsiUpperCase(S); // Pour ignorer la casse.
for i:=1 to Length(S) do
Inc(Occurences[S[i]]); // On incrémente.
Max:='A'; // Par défaut, le premier
{ Recherche du plus grand. }
for C:=Low(Occurences) to High(Occurences) do
if Occurences[C] > Occurences[Max] then
Max:=C;
Lettre:=Max;
Nbre:=Occurences[Max];
end;
Personnellement, je trouve que ma
procedure est plus efficace car celle de ni69, incomplete,
necessiterait que la chaine soit parcourue 26 fois au lieu d'une pour
la mienne.
Celle de sim51 reprends l'idée de ni69 avec sa boucle for i:=1 to 26, et, donc, n'est pas plus performante.
En ce qui concerne les accents, la fonction de grandvizir que te
propose ni69 n'est pas très performante. Je posterai une source dès que
j'aurais fini de travailler la mienne.
Cepandant, tu peux l'inclure avant le traitement de la chaine, c-à-d au tout début de la procedure.
Allez, bonne chance, mais tu es dans la bonne voie
@ ++ Florent
Si tu ne te plantes pas ......
tu ne poussera jamais