Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1474 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Tester 3 lettres

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Tester 3 lettres

n°1026864
Emmylou
Posté le 27-03-2005 à 19:48:08  profilanswer
 


Bonjour.
 
 
J'ai un problème :D
 
Je dois écrire un programme (en C, donc) qui compte le nombre d'occurence d'un mot de trois lettres dans un texte. (Texte qui est ouvert dans un fichier)
 
J'arrive à compter le nombre d'occurence d'une lettre, mais pour ce qui est du groupe de trois lettres, ça fait deux jours que je tourne dans tous les sens les éventualités qui passent dans ma tête, mais rien à faire. Arrive pas  :sarcastic:  
 
Est-ce que vous pourriez m'aiguiller siouplé ?
:D
 
Merci !
 
 
Emmylou.
 
 

mood
Publicité
Posté le 27-03-2005 à 19:48:08  profilanswer
 

n°1026866
matafan
Posté le 27-03-2005 à 19:51:53  profilanswer
 

Tu peux faire des strstr() en reprenant à chaque fois à la position renvoyée + 3.

n°1026868
Emmylou
Posté le 27-03-2005 à 19:54:11  profilanswer
 


 Euh.
 
J'vais avoir l'air bête, hein, mais j'ai pas tout compris.
 
...
 
[Désolée...]
 

n°1026869
cricri_
Posté le 27-03-2005 à 20:01:52  profilanswer
 

StrStr() te retourne un pointeur sur l'occurence trouvée, donc tu en fais un autre en donnant comme chaine de départ la chaine précédente + 3 afin de recommencer la recherche après.

n°1026871
Emmylou
Posté le 27-03-2005 à 20:05:29  profilanswer
 


Je sais que je suis affreusement chiante, mais strstr() ne figurant pas dans mon catalogue réduit (j'ai commencé les cours de prog en janvier) de fonctions, j'avoue avoir des réticences à me lancer dans quelque chose comme ça. Vu qu'en plus j'le connais carrément pas.
 
J'n'ai pas précisé que je dois écrire une fonction qui compte le nombre d'occurences du groupe de lettres que je saisi au clavier dans le programme principal.
C'était peut-être important ?
 
:sarcastic:

n°1026877
KangOl
Profil : pointeur
Posté le 27-03-2005 à 20:22:40  profilanswer
 

man strstr


---------------
Nos estans firs di nosse pitite patreye...
n°1026878
Chronoklaz​m
Posté le 27-03-2005 à 20:24:03  profilanswer
 

Et les automates à piles c'est pour les chiens ?  :D


Message édité par Chronoklazm le 27-03-2005 à 20:24:17

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°1026883
Emmylou
Posté le 27-03-2005 à 20:29:20  profilanswer
 


Pardon ?

n°1026885
Chronoklaz​m
Posté le 27-03-2005 à 20:35:01  profilanswer
 

Soit une pile (ou meme un petit buffer), tu lis un caractere, tu le stocke dans la pile en ayant verifier qu'elle ne contient pas plus de 3 caracteres, si c'est le cas et que tu lis un espace tu incremente ton compteur et ainsi de suite ...
Je te laisse gerer le cas ou t'as plus de 3 carac dans la pile :)


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°1026889
Emmylou
Posté le 27-03-2005 à 20:45:46  profilanswer
 


o_O
 
Et ça, ça va me permettre de trouver le nombre d'occurence du mot de 3 lettres que je cherche ?
 
Je me suis peut-être mal expliquée.
 
Je suis sensée écrire une fonction qui prend en argument une chaîne s de 3 caractères et retourne le nombre d'occurences de cette chaîne dans un fichier.
Et dans mon programme principal, je dois ouvrir le dit-fichier et demander à l'utilisateur de choisir un mot de 3 lettres auquel j'appliquerai la fonction écrite précédemment.
 
...
 

mood
Publicité
Posté le 27-03-2005 à 20:45:46  profilanswer
 

n°1026893
dark86
Posté le 27-03-2005 à 20:50:02  profilanswer
 

Si tu as deja fait le test pour ue lettre, pour 3 c'est pareil, sauf que dans ton test :
char* p
if(*p=='a') deviens :
if(*p=='a' && *(p+1)=='b' && *(p+2)=='c')
en rajoutant un test pour verifier que tu ne sors pas du fichier en p+1 et p+2

n°1026931
Emmylou
Posté le 27-03-2005 à 22:05:52  profilanswer
 


Euh, oui mais je suis sensée me servir de chaines de caractères et je ne connais pas les lettres que je teste...
 
Bon, j'ai fait ça :
 
int NbOccurr (char s[])
{
    int nb_car, i;
    char m[4];
    nb_car=0;
    fscanf(f, "%s", &m);
    i=0;
    while (s[i]!=EOF && s[i+1]!=EOF && s[i+2]!=EOF)
    {
          if (m[0]==s[i] && m[1]==s[i+1] && m[2]==s[i+2])
          nb_car++;    
          i=i+3;
    }
    return nb_car;
}
 
 
Mais ça ne marche pas
 
:'(

n°1027007
Deadog
Dain Bramaged
Posté le 27-03-2005 à 23:57:40  profilanswer
 

fscanf(f, "%s", &m);
 
m est déjà une adresse (pour vulgariser)
donc pas besoin du & devant
 
j'attire ton attention sur le fait que c'est pas correct d'utilier un scanf de cette façon pour lire une chaîne de caractère
%3s serait mieux dans ce cas la (si j'me souviens bien, pke j'utilise pour ainsi dire jamais les scanf)
 
EOF n'est pas très indiqué ici, '\0' serait mieux puisque ce n'est qu'une chaîne de caractère
 
i=i+3; ==> i += 3; ;)
 
 
edit : ainsi que les { et } pour ton if, car tu as 2 instructions à éxécuter ;)
pense aussi à faire incrémenter i quand tu ne trouve pas de suite de caractères


Message édité par Deadog le 28-03-2005 à 16:38:10
n°1027379
Emmylou
Posté le 28-03-2005 à 16:01:30  profilanswer
 


[Ca veut dire quoi les * que tout le monde met partout et dont ma chère prof ne m'a jamais parlé ?]
 
Tenant compte de ces conseils, j'ai changé :
 
int NbOccurr (char s[])
{
    int nb_car, i, a;
    char l;
    nb_car=0;
    l=getc(f);
    a=0;
    while (l!=EOF)
    {
          for (i=0;i<=2;i++)
          {
              if (l==s[i]) a++;
              l=getc(f);    
          }
          if (a==3) nb_car++;
          a=0;
          i=0;
          l=getc(f);
    }
    return nb_car;
}
 
 
Mais ça marche toujours pas.
Ahah.

n°1027386
push
/dev/random
Posté le 28-03-2005 à 16:07:20  profilanswer
 

Achète toi un livre comme celui-çi par exemple http://www.amazon.fr/exec/obidos/A [...] 03-0104201
 
pour au moin avoir les bases parceque sinon c'est pas la peine, tu perds ton temp et tu fais perdre celui des autres sur des banalités, c'est pas méchant c'est juste vrai.

n°1027392
Emmylou
Posté le 28-03-2005 à 16:14:39  profilanswer
 


Merci.
C'est à elle
http://www.dil.univ-mrs.fr/~godbert/
qu'il faut dire ça.
 
En attendant, il aurait suffi de dire 'y a ça qui va pas et en changeant ça, ça marche', le temps aurait été moins perdu...
C'est pas méchant, juste vrai.

n°1027404
Deadog
Dain Bramaged
Posté le 28-03-2005 à 16:31:49  profilanswer
 

les * sont ce qui caractèrise les adresses mémoires (ou pointeur)
visiblement tu n'as pas encore vu ça donc ne t'en occupe pas ;)  
 
reprend ce que je t'ai dit, et pê que ça marchera [:spamafote]


Message édité par Deadog le 28-03-2005 à 16:37:28
n°1027430
Sve@r
Posté le 28-03-2005 à 17:10:41  profilanswer
 

Emmylou a écrit :

[Ca veut dire quoi les * que tout le monde met partout et dont ma chère prof ne m'a jamais parlé ?]
 
Tenant compte de ces conseils, j'ai changé :
 
int NbOccurr (char s[])
{
    int nb_car, i, a;
    char l;
    nb_car=0;
    l=getc(f);
    a=0;
    while (l!=EOF)
    {
          for (i=0;i<=2;i++)
          {
              if (l==s[i]) a++;
              l=getc(f);    
          }
          if (a==3) nb_car++;
          a=0;
          i=0;
          l=getc(f);
    }
    return nb_car;
}
 
 
Mais ça marche toujours pas.
Ahah.


 
Euh... d'où tu le sors ce "f" ?
Je comprends bien qu'il s'agit du fichier que tu lis. Ce que je demande, c'est pourquoi ce "f" n'est pas défini dans la fonction.
Oups... je commence à penser qu'il s'agit ici d'une variable globale. Pas joli. Bon, c'est pas grave mais tu devrais apprendre à éviter d'utiliser des variables globales car c'est source de confusion (la preuve, j'en suis réduit à supposer que cette variable est bien définie et bien initialisée) et on peut toujours s'en passer.
Par ailleurs, ne dis pas que tu ne connais pas le "*" puisque ce fameux "f" doit probablement être de type "FILE *"
 
Maintenant, on va parler d'algorithmie. C'est la traduction en ordres simples, souvent dans un pseudo langage, de la résolution d'un problème
- Tu commences par lire un octet dans ton fichier
- Ensuite, si cet octet correspond à ta première lettre, tu lis 3 octets à suivre, tant que les octets lus correspondent aux lettres de ta chaîne. Donc, déjà, tu risques de lire un octet de trop (tu as déjà lu un premier octet).
- Puis tu refais une lecture supplémentaire (deux octets lus en trop). Il est fortement probable que tu sautes des occurences
Tu devrais repenser la logique de ta solution avant de la traduire en C
 
On peut te donner une solution mais il vaut mieux que tu la trouves par toi-même. Ca te sera beaucoup plus profitable.
Enfin essaie d'utiliser des noms de variable significatifs tu t'y retrouveras beaucoup mieux. "nb_car" correspond au nombre d'occurences et pas au nombre de caractères. "a" correspond au nombre de caractères mais faut le deviner.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1027435
Emmylou
Posté le 28-03-2005 à 17:22:19  profilanswer
 


Effectivement, le 'f' est de type FILE défini en variable globale. (L'initiative n'est pas de moi, on m'a dit que c'était mieux, peut-êter parce que mon expérience se réduit à trois mois)
Alors, oui, je connais les * puisque je connais les FILE mais je ne l'avais jamais vu autre part, ça m'a un peu perturbée, ces * partout.  
 
Hem.
J'avoue que celui-ci n'était pas particulièrement joli, comme algorithme (bien que l'esthétique informatique me passe quelques kilomètres au dessus)
J'en ai donc un autre, qui apparemment ne marche pas non plus (ou bien je suis folle, ce qui est aussi possible) où je lis caractère par caractère.
Je teste le premier, s'il correspond au premier de ma chaîne, je teste celui d'après, et si celui-ci correspond au 2d de ma chaîne je teste une 3e fois et j'incrémente s'il y a encore correspondance.
 
Puis je ne demandais pas une solution toute faite, mes principes s'y refusent [et d'ailleurs, le cas échéant, j'aurais fait mon embêtante s'il y avait eu quoi que ce soit que je comprenais pas :D], juste un éventuel aiguillage (ou 'ton truc est complètement faux' :p )
 
 
Merci déjà pour tout ce que j'ai appris :)

n°1027466
Sve@r
Posté le 28-03-2005 à 17:51:19  profilanswer
 

Emmylou a écrit :

Effectivement, le 'f' est de type FILE défini en variable globale.

Tu veux dire "FILE *" (c'est très important de rester très précis quand on parle de pointeurs)
 

Emmylou a écrit :

(L'initiative n'est pas de moi, on m'a dit que c'était mieux, peut-êter parce que mon expérience se réduit à trois mois)

Mieux aujourd'hui pour simplifier. Plus tard, on te dira qu'en fait il ne faut pas. Prépare toi à cette éventualité
 

Emmylou a écrit :

Alors, oui, je connais les * puisque je connais les FILE mais je ne l'avais jamais vu autre part, ça m'a un peu perturbée, ces * partout.

Plus tard tu seras très à l'aise avec une ou deux étoiles (au delà, ça devient invivable)
 

Emmylou a écrit :

J'en ai donc un autre, qui apparemment ne marche pas non plus (ou bien je suis folle, ce qui est aussi possible) où je lis caractère par caractère.
Je teste le premier, s'il correspond au premier de ma chaîne, je teste celui d'après, et si celui-ci correspond au 2d de ma chaîne je teste une 3e fois et j'incrémente s'il y a encore correspondance.

En fait, le problème ne vient pas de la première lecture mais souvent des lectures suivantes. D'où est-ce que tu repars si seulement une ou deux lettres correspondent ? Est-ce que tu relis quand-même 3 nouvelles lettres ? Imagine que ton fichier commence apr "ABABCDE" et tu cherches "ABC". Tu commences par comparer "ABC" avec "ABA" => pas bon. Est-ce que tu repars sur "BCD" ou sur le "ABC" suivant ?
Essaye de travailler avec un papier. Pose tes lettres dans tes cases et déroule ton algorithme en imagination. J'espère que tu réussiras. En tout cas, ton idée est la bonne.
 

Emmylou a écrit :

Merci déjà pour tout ce que j'ai appris :)

On est là pour ça


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1027487
Chronoklaz​m
Posté le 28-03-2005 à 18:11:54  profilanswer
 

Je n'ai peut etre pas compris le probleme mais pour moi un "mot de 3 lettres" est une suite de 3 lettres puis un espace, donc quand on lit "ABABCDE"; on lira "A" puis "B" puis "A" ensuite avant de comparer "ABA" avec la chaine qu'on cherche on verifie si le 4ieme caractere est un espace ou un point etc ? Si c'est le cas on passe directement au mot suivant sans se preoccuper de la comparaison.
 
Non ?
 
EDIT : Bon pour cette histoire d'espace, en C il y a une fonction qui s'appelle ungetc qui remet un caractere lu dans un fichier ... ca peut eventuellement servir (j'en dis pas plus)


Message édité par Chronoklazm le 28-03-2005 à 18:21:47

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°1027514
Emmylou
Posté le 28-03-2005 à 18:30:02  profilanswer
 

Mais...
quand je fais ça
 
while (l!=EOF)
    {
          if (l==s[0])
              {
                           l=getc(f);
                           if (l==s[1])
                           {
                                         l=getc(f);
                                         if (l==s[2])
                                         {
                                                     occur++;
                                                     l=getc(f);
                                         }
                                         
Il faudrait que je mette un 'else' à chaque 'if' qui referait à chaque fois ? Ca n'a pas de sens, je n'aurais jamais fini !  
Pourtant, il faudrait qu'à chaque fois que les lettres ne correspondent pas je refasse le test à partir du début...
[Je pense 'si l n'est pas égale à s[0] on en prend une autre, on réessaie, mais dans ce cas, si c'est encore pas égal à s[0]... Ensuite, si c'est égal à s[0], mais pas à s[1], on en prend une autre et on recommence du début, et si c'est égal à s[1] mais pas à s[2], on...' O_O ]
 
 
Est-ce qu'il existe une [... Je cherche le bon mot, je suppose que je ne l'ai pas] fonction (?) qui me permettrait de revenir au début et tester la lettre avec la première de mon mot ?
 
 

n°1027531
Deadog
Dain Bramaged
Posté le 28-03-2005 à 18:45:23  profilanswer
 

mais ton premier truc marchait très bien mis à part qql erreurs !!
 

Code :
  1. while (s[i]!=0 && s[i+1]!=0 && s[i+2]!=0)
  2.     {
  3.           if (m[0]==s[i] && m[1]==s[i+1] && m[2]==s[i+2])
  4.             nb_car++;
  5.            
  6.           i++;
  7.     }


 
ça c'est ce que tu avais fait au début avec qql trucs corrigé
le principe m'a l'air bon dans un monde parfait
 
m constitue les 3 lettres recherchés
s constitue toutes une chaîne de caract contenant le texte dans lequel tu recherches


Message édité par Deadog le 28-03-2005 à 18:46:06
n°1027536
Emmylou
Posté le 28-03-2005 à 18:48:49  profilanswer
 


Et sachant que le texte que je recherche est rangé dans mon fichier f, pour que s corresponde à ce texte, il suffirait que je fasse fscanf (f,"%s",s)  ?

n°1027559
Deadog
Dain Bramaged
Posté le 28-03-2005 à 19:01:44  profilanswer
 

non, car tu ne connais sans doute pas d'avance (cad au moment ou s'éxécute ton programme) le nb de caractère dans ton fichier et tu risques donc le débordement de mémoire
 
cette partie la est à changé, mais ce n'est pas bien compliqué
tu fais ta fonction pour qu'elle puisse prendre 2 paramètres : char s[] et char m[]
 
et tu appelles ta fonction en lui fournissant ce dont elle a besoin
et pour lui fournir s[], tu utilises, par expl, fgets comme ceci :
 

Code :
  1. char buffer[BUFSIZ];
  2. while(fgets(buffer, BUFSIZ-1, f) != NULL) {
  3.   NbOccurr(buffer, "ABC" );
  4. }


 
sachant que BUFSIZ est déjà définie dans la lib standard ;)
 
(avec pê tes modif à faire, j'ai pas testé  :sleep:  )
 


Message édité par Deadog le 28-03-2005 à 19:03:15
n°1027586
Emmylou
Posté le 28-03-2005 à 19:21:28  profilanswer
 

Je n'ai pas le droit de changer ma fonction pour qu'elle prenne deux paramètres.
[Si j'avais le droit de choisir, j'aurais balancé les profs par la fenêtre]

n°1027588
Deadog
Dain Bramaged
Posté le 28-03-2005 à 19:22:25  profilanswer
 

bon bah fait ça dans la fonction elle même alors ;)
et dans le while tu mes ce qu'il faut [:spamafote] ;)

n°1027817
Sve@r
Posté le 28-03-2005 à 21:39:55  profilanswer
 

Chronoklazm a écrit :

Je n'ai peut etre pas compris le probleme mais pour moi un "mot de 3 lettres" est une suite de 3 lettres puis un espace, donc quand on lit "ABABCDE"; on lira "A" puis "B" puis "A" ensuite avant de comparer "ABA" avec la chaine qu'on cherche on verifie si le 4ieme caractere est un espace ou un point etc ? Si c'est le cas on passe directement au mot suivant sans se preoccuper de la comparaison.
 
Non ?
 
EDIT : Bon pour cette histoire d'espace, en C il y a une fonction qui s'appelle ungetc qui remet un caractere lu dans un fichier ... ca peut eventuellement servir (j'en dis pas plus)


 
Oui, je crois que quelque part il y a une incompréhension sur l'énoncé du problème.
Est-ce que le problème est de rechercher le nombre de fois où on trouve une occurence de 3 lettres dans une suite de lettres... ou est-ce que le problème est de rechercher les mots qui ont 3 lettres et dont les lettres correspondent aux lettres demandées ?


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1032021
fra0
Posté le 01-04-2005 à 01:30:44  profilanswer
 

Code :
  1. //  la base
  2. unsigned int laClef(unsigned char mot[3])
  3. {
  4.     return mot[2]*65536+mot[1]*256+mot[0]; // trouve un chiffre qui représente
  5. }
  6. // et compte tous les triplets ;)
  7. void compterLes3Mots(char *leTexte, unsigned int laTaille)
  8. {
  9.     unsigned int *lesTuples,indice;
  10.     lesTuples=(unsigned int*)calloc(1<<8*3,sizeof(unsigned int));
  11.     for(indice=0;indice<=laTaille-3;indice++)
  12.     {
  13.         lesTuples[laClef(&leTexte[indice])]++;
  14.     }
  15. /* et voila,
  16. tous les 3-mots de la chaine sont dans ce tableau,
  17. normalement on peut écrire :
  18. printf("cat est écrit %d fois",lesTuples[laClef("cat" )]);
  19. printf("DOG est écrit %d fois",lesTuples[laClef("DOG" )]);
  20.  
  21. unsigned int x=7*256*256+7*256+7;  
  22. printf("si le fichier est un nombre en base 256, 777 y apparraît %d fois",lesTuples[laClef((char*)&x)]);
  23. ou bien sortir des listes (triées) :
  24. for(indice=0;indice<(1<<8*3);indice++) // pour tous les triplets
  25. {
  26.     if(lesTuples[indice]>=7) // qui apparaissent au moins 7x dans leTexte...
  27.  {
  28.   ///...
  29. */
  30.     free(lesTuples);
  31. }
  32. //fra - 0 garanties//

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Tester 3 lettres

 

Sujets relatifs
[SQL]Insérer un espace toutes les 2 lettres dans un champ [Résolu]comment tester si un nombre est un entier
Tester une décimale ?Tester la validité d'un URL
tester la presence d'une table dans la BDtester si une webradio est pleine !
[JS] Script de détection flash : comment le tester ?Une appli graphique pour tester ses expressions XPath ??
tester un site sur differents navigateurs[SQL] Récuperer une chaine sans les deux premieres lettres ?
Plus de sujets relatifs à : Tester 3 lettres


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR