Occurence caractère

Bonjour,
j'aimerais calculer l' occurence de chaque caractère de "chaine2" mais cela ne marche pas, voici mon code source en C.
Merci de m'aider.

for (i=0;i<taille_chaine2;i++)
{
a=chaine2[i];
for (j=0;j<taille_chaine;j++)
{
if (a==chaine[j])
cpt++;
}
}
Configuration: Windows Vista
Firefox 3.0.7

17 réponses

  • Votes
  • Date
  • Date décroissante
Résumé de la discussion

Calculer l'occurrence de chaque caractère de chaîne2 en C pose problème dans le code fourni, qui utilise des boucles imbriquées et des tests d'égalité sans gestion des caractères uniques. Réponses diverses proposent notamment de factoriser dans une fonction nbOccur qui compte, pour chaque caractère de chaîne1, le nombre d'occurrences dans chaîne2 via deux boucles imbriquées et un compteur. En complément, une approche efficace consiste à utiliser un tableau de fréquences de 256 éléments pour les caractères ASCII, puis à incrémenter les indices correspondants lors de l'itération sur chaîne2.

Bobot (l’IA à votre service)
  1. Bon, j'avais essayé de faire simple, mais puisque que vous voulez en savoir plus voici mon code complet :

    #include<stdio.h>
    #include<conio.h>
    #include<string.h>
    #include<iostream>
    //#DEFINE taille 30

    int main(int argc, char*argv[])
    {
    char chaine[30]="abbabbaacffcrr";
    char chaine2[30],chaine3[30],a;
    int cpt,taille,i,j,cpt2,cpt3=0;
    int k=0;

    taille=strlen(chaine);
    cpt2=taille;
    printf("%s\n",chaine);

    for (i=0;i<taille;i++)
    {
    for (j=1+i;j<taille;j++)
    {

    if (chaine[i]==chaine[j]){
    chaine[j]='*';

    }
    }
    }

    for (i=0;i<taille;i++)
    {
    if (chaine[i]=='*')
    cpt2--;
    }

    for (j=0;j<taille;j++)
    {
    if (chaine[j]!='*'){
    chaine2[k]=chaine[j];
    k++;}
    }

    for (i=0;i<cpt2;i++)
    {
    a=chaine2[i];
    for (j=0;j<taille;j++)
    {
    if (a==chaine[j])
    cpt3++;
    }
    printf("%d-",cpt3); //le printf ne m'affiche le bon nombre de caractere
    }

    printf("\n%s\n%s\n",chaine,chaine2);
    printf("nbre de caractere different : %d\n",cpt2);

    for (i=0;i<cpt2;i++)
    {
    printf("nbre de %c : \n",chaine2[i]);
    }

    while(!kbhit());
    }
    1. Les tailles sont prédéfinies, donc il n'y a pas d'erreur possible sur les tailles.
      1. Contributeur
        Ca me fait peur quand tu dis prédéfinis. ^^ L'erreur vient peut-être de là.
        Poste ta définition des tailles ainsi que celle des chaînes.
    2. Contributeur
      Salut,
      Qu'est-ce qui ne marche pas ?
      Car je ne vois pas d'erreur dans ton code. A moins bien sûr que la taille des chaînes aient mal été calculées ou que cpt n'ait pas été défini ou des erreurs du genre.
      Pourrais-tu poster aussi la déclaration des variables utilisées (i,j,a,taille_chaine,cpt,chaine,...) et la définition de taille_chaine, chaine, etc.
      A noter que ta variable "a" est inutile. Tu peux directement comparer chaine[i] avec chaine[2].
      1. tester ce code:

        int calculer_occurence(Char s1[],char s2[])
        {
        int nb_occ=0;
        int i,j;

        for(i=0;i<strlen(s1),i++) /*strlen(s): retourne la longueur de la chaine elle se trouve dans string.h ou stdlib.h */
        for(j=0;j<strlen(s2),j++)
        if(s1[i]==s2[j])
        nb_occ++;
        return(nb_occ);

        }
        1. Contributeur
          Oui, donc les tailles des chaînes ne sont pas pré-définies ^^. Elles sont tout simplement calculées. Donc, là ça me va mieux.
          Sinon, tu gaspilles beaucoup de variables. Certes, ce n'est pas gênant, mais en plus ça perd un peu en lisibilité.

          Tout simplement, tu codes une fonction annexe qui va calculer le nombre d'occurences. C'est plus propre que de tout mettre dans le main.

          Par exemple :
          int nbOccur(const char *chaine1, const char *chaine2) {
              size_t i,j;
              int res=0;
              for(i=0;i<strlen(chaine1);i++)
                  for(j=0;j<strlen(chaine2);j++)
                       if(chaine1[i]==chaine2[j])
                            res++;
              return res;
          }
          

          Sinon, n'inclue pas iostream si tu fais du C.
          1. Bonjour Fiddy:
            c'est quoi le size_t ???
          2. Contributeur
            @AmineKalaaSalut,
            c'est quoi le size_t ???
            C'est le type officiel pour les tailles (non signé). C'est ce que renvoie sizeof, strlen, ...
        2. Je ne sais pas ou ton programme ne marche pas( c'est pas dit !)
          Me basant sur ton post 1, il y a un problème de cpt qui s'incrémente quelque soit le caractère.
          Je te propose cet algorithme

          pour chaque caractère de la chaine(indice i)
          
          	mettre compteur à 0
          
          	vérifier que ce caractère existe dans un tableau (à 2 dim)
          	si n'existe pas
          		redimensionner le tableau 
          		écrire le caractere dans le tableau
          		pour chaque caractere de la chaine (indice j)
          			comparer avec le caractere d'indice i
          			si égal
          				compteur +1
          			fin si
          		fin pour (j)
          		ecrire le compteur dans le tableau
          			
          	si existe 
          		ben on fait rien puisqu'il a déjà été traité
          	fin s
          fin pour(i)


          a la fin on obtient un tableau contenant chaque caractère et son nombre d'occurences dans la chaine.
          A+
          1. Contributeur
            Salut,
            Me basant sur ton post 1, il y a un problème de cpt qui s'incrémente quelque soit le caractère.
            Non, il n'y a pas d'erreurs dans son post 1. Il y a bien le "if" ;-)).
          2. @fiddy
            j'ai pas bien saisi l'nance il voudrait calculer l'occurrence de chaque caractère donc il faut reserver un tableau d'entiers de taille la longueur du chaine 1::
            void calculer_occurence(char s1[],char,s2[], int t[],int n)/*tableau passer en paramètre avec sa taille*/
            {
              int i;
             int j;
             /* initialisatoin du tableau */
             for(i=0;i<n; t[i]=0;i++);
            
             /*traitement*/
            for(i=0;i<n/*strlen(s1);i++)
               for(j=0;j<strlen(s2);j++)
                 if(s1[i]==s2[j])
                     t[i]++;
            }
            
            <code>
            ca marche !!!
          3. @fiddyBen oui et non ! effectivement le compteur ne s'incrémente que SI chaine(i)= chaine(J), mais comme le compteur n'est pas remis à 0 entre chaque indice i, on aura un résultat global inexploitable !!!
        3. oui, mais en fin de traitement on obtient un tableau de chiffres sans savoir à quels caractères ils se rapportent et on aura plusieurs fois un nombre d'occurences se rapportant au même caractère.

          Ainsi si la chaine est BABAR (n'importe quoi!) on obtiendrait:
          2
          2
          2
          2
          1

          ce serait mieux si on avait
          B=2
          A=2
          B=2
          A=2
          R=1

          l'algo que je proposais permet d'obtenir:
          B=2
          A=2
          R=1

          A+
          1. la question est de chercher le nb d'occurrence des caractères de chaine1 dans chaine 2 donc on s'en fou des caracterer de chaine1 on va juste les lire...
            selon la solution que j'ai proposé on obtient interprété comme suit:
            le caractère n° i de chaine1 c'est répété t[i]fois dans chaine2..
            si on veut faire mieux on doit passer à la notion de structure.
            1. Salut Albert, merci pour ton algo mais es que tu pourrais me le donner en C parce que moi et l'algo^^, et surtout je n'ai pas très bien compris quand tu parle de redimensionner le tableau
              1. bonjour jeremy
                pourqoi pas tester le code que j'ai mensionné au dessu?? ca marche !!
            2. Ah ben oui j'avais pas tout compris l'expression du besoin!
              J'étais parti sur une autre idée

              Milles excuses
              1. Ah ben non, en relisant le post 5, dans chaine2 on trouve bien chaine, et le but est il de déterminer le nombre d'occurrences de chaine dans chaine 2 ou bien de déterminer le nombre d'occurences de caractères dans chaine2( ou chaine puisque si j'ai tout compris c'est la même)
                1. Il faut trouver le nombre d' occurence dans chaine1, tu l'a bien expliqué dans le post 13, c'est exactement ça qu'il
                  faut faire.
                  1. Contributeur
                    Tu veux le nombre d'occurences d'une chaîne dans une autre globale ? Ou un histogramme donnant les occurences de chaque lettre d'une chaîne dans une autre ?
                    Par exemple
                    abcd et bcde
                    Tu veux que ça te donne : 3 ou que ça donne : b 1, c 1, d, 1 ?
                    Cdlt
                2. Par exemple si j'ai "abracadabra", le résultat doit être :
                  a = 5
                  b = 2
                  r = 2
                  c = 1
                  d = 1
                  1. Contributeur
                    Euh là c'est encore différent.
                    Tu parlais de deux chaînes au début.
                    Tu veux le nombre d'occurences de chaque lettre constituant un mot ou le nombre d'occurences des lettres dans un autre mot ?
                3. Je veux le nombre d' occurences de chaque lettre constituant un mot ou une phrase.
                  1. Contributeur
                    Ok, voici un programme qui répond à tes attentes :
                    #include <stdio.h>
                    #include <string.h>
                    #include <ctype.h>
                    
                    int main(void){
                        int histo[26]={0};
                        const char *phrase="ceci est un test";
                        size_t i;
                    
                        //remplissage de l'histogramme
                        for(i=0;i<strlen(phrase);i++){
                            char c=tolower(phrase[i]);
                            if( c>='a' && c<='z' )
                                histo[c-'a']++;
                        }
                    
                        //affichage
                        for(i=0;i<26;i++)
                            if( histo[i] )
                                printf("%c: %d\n",i+'a',histo[i]);
                    
                        return 0;
                    }