IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

un petit histogramme pas facile


Sujet :

C

  1. #1
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut un petit histogramme pas facile
    Bonsoir à tous , j'ai l'exercice suivant :

    écrire un programme en C qui affiche l'histogramme de la longueur ds mots rencontrés en entrée .
    fonctions autorisées : getchar , putchar , printf
    utilisation de boucles , variables , tableaux ( 1 seul tableau ) , rien d'autre .

    Voici l'algorithme en français :

    1Je parcours la chaine de caractère en entrée , chaque fois que j'arrive à la fin d'un mot je compte les lettres du mot , et j'incrémente la case du tableau correspondante , si le mot fait 5 lettres j'incrémente la case 5 .

    2. je parcours le tableau tout en affichant l'histogramme , et une autre variable lit la valeur dans chaque case et affiche le signe _ tant que ce n'est pas fini .

    exemple de ce que doit faire le programme :

    phrase reçue en entrée :

    Bonsoir , comment te portes tu petit coq , hi hi .

    résultat à l'écran :

    1:
    2: ____
    3: _
    4:
    5: _
    6: _
    7: _
    8: _
    9:

    ce qui veut dire , 0 mot de 1 lettre , 4 mots de 2 lettres ...

    voici mon code en C , je sais qu'il est presque bon mais il y a une petite erreur à mon avis sur la fin avec la variable i , car mon programme m'affiche un défilement infini de _ _ _ _ _

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include  <stdio.h>
     
    int main(void) 
    {
      int a, i, j;;
      int nlettre[10];
      int nl = 0;
     
     
     
      while ( ( a = getchar() ) != EOF && nl < 10) 
    {
        if ( a == ' ' || a == '\n' || a == '\t' )
          nl=0;
        else
          nl++;
        nlettre[nl]++;
      }
     
      for ( j = 0; j < 10; j++) 
    {
        printf("%d :", j);
        for (  i=0; i<nlettre[j]; i++) 
    {
          printf("_");
        }
      }
      return 0;
    }
     
    le début est bon , je suis certain que le blème vient de la dernière boucle for...
     
    PS : je n'ai pas besoin de rajouter de variables ni de tableaux , tout y est , mais mal disposé je pense , merci de votre aide .

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faut initialiser ton tableau à zéro avant. Sinon, il peut contenir n'importe quoi. En fait, il ne t'affiche pas un nombre infini de lettres, mais un nombre infini.

    -- edit: Ce que j'avais écrit là était une connerie, avec le <on peut afficher au plus 2 milliards à chaque passage, donc 20 milliards de '_' affichés... --

    Soit directement dans la déclaration, soit avec une petite boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for( j=0 ; j<10 ; j++)
    	nLettre[j] = 0;
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: un petit histogramme pas facile
    Citation Envoyé par Bibouda
    Voici l'algorithme en français :

    1Je parcours la chaine de caractère en entrée , chaque fois que j'arrive à la fin d'un mot je compte les lettres du mot , et j'incrémente la case du tableau correspondante , si le mot fait 5 lettres j'incrémente la case 5 .

    2. je parcours le tableau tout en affichant l'histogramme , et une autre variable lit la valeur dans chaque case et affiche le signe _ tant que ce n'est pas fini .
    Le codage de l'algo est faux. L'enregistrement du compteur de lettres est mal placé...
    Pas de Wi-Fi à la maison : CPL

  4. #4
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    dans la boucle , j'ai effectivement rajouter cette ligne :

    nLettre[j] = 0; , et là mon programme m'affiche :

    9:

    0 mot de 9 lettres , ya du progrès , je pense qu'on y est presque , il me manque plus que

    1:
    2:
    3:
    ...

    peut être que je devrais incrémenter le tableau juste après , non?

  5. #5
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    emmanuel , en fait il n'y a pas de compteur de mot , mais un compteur qui compte les lettres de chaque mot , c'est la 1ere phase , donc je comprends pas pq tu dis qu'il est mal placé , çà concorde avec mon algo en français..

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Bibouda
    emmanuel , en fait il n'y a pas de compteur de mot , mais un compteur qui compte les lettres de chaque mot , c'est la 1ere phase , donc je comprends pas pq tu dis qu'il est mal placé , çà concorde avec mon algo en français..
    Oui, pardon. Compteur de lettres (nl). L'incrément est correct, mais c'est au moment où on trouve le séparateur de mot qu'il faut l'enregistrer puis le remettre à 0...
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while ( ( a = getchar() ) != EOF && nl < 10)
    {
        if ( a == ' ' || a == '\n' || a == '\t' )
          nl=0;
        else
          nl++;
        nlettre[nl]++;
      }
    en français çà me donne :

    tant que le caractère en entrée est différent de EOF et que nl infénieur à 9 , et si
    le caractère entrée est un espace , une fin de ligne ou une tabulation , le nombre de lettres vaut 0.
    sinon on compte le nombre de lettres , et on incrémente la case du tableau correspondante .

    Le séparateur de mot , ben c'est quand nl = 0 , je vois pas comment je peux l'enregistrer et il se remettra à 0 chaque fois que if (..) sera vérifiée , j'avoue que je saisi pas là ...

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Bibouda
    tant que le caractère en entrée est différent de EOF et que nl infénieur à 9 , et si
    le caractère entrée est un espace , une fin de ligne ou une tabulation , le nombre de lettres vaut 0.
    sinon on compte le nombre de lettres , et on incrémente la case du tableau correspondante .
    Ben non. Il ne faut incrémenter le compteur que quand on connait la valeur, pas avant, sinon, on incrémente pas le bon... Ce moment, c'est la fin du mot.
    Le séparateur de mot , ben c'est quand nl = 0 , je vois pas comment je peux l'enregistrer et il se remettra à 0 chaque fois que if (..) sera vérifiée , j'avoue que je saisi pas là ...
    Juste avant de remettre à zéro ! C'est de l'algo élémentaire...
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    franchement je ne vois pas ce que çà fait en C , je ne fais pas encore d'algo , c'est justement l'intérêt de débuter sans faire d'algo , c'est de chercher des bonnes méthodes , mais là j'ai un peu de mal , le code donne quoi?

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Bibouda
    franchement je ne vois pas ce que çà fait en C , je ne fais pas encore d'algo , c'est justement l'intérêt de débuter sans faire d'algo , c'est de chercher des bonnes méthodes , mais là j'ai un peu de mal , le code donne quoi?
    Exactement ce qui est décrit :
    Il ne faut incrémenter le compteur que quand on connait la valeur, pas avant, sinon, on incrémente pas le bon... Ce moment, c'est la fin du mot.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while ((a = getchar()) != EOF && nl < 10)
    {
        if (a == ' ' || a == '\n' || a == '\t')
        {
            nlettre[nl]++;
            nl=0;
        }
        else
        {
            nl++;
        }
    }
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    mdr , merci , voici le code final , et il ne marche pas , çà fait 2 semaines que je demande de l'aide sur internet , PERSONNE n'a trouvé la solution , c'est incroyable , ingénieur , débutant , étudiant , tt le monde se plante lol :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include  <stdio.h>
     
    int main(void)
    {
      int a, i, j;;
      int nlettre[10];
      int nl = 0;
     
     
     
      while ( ( a = getchar() ) != EOF && nl < 10)
    {
        if ( a == ' ' || a == '\n' || a == '\t' )
    {
    nlettre[nl]++;
          nl=0;
    }
        else
    {
          nl++;
     }
     }
     
      for ( j = 0; j < 9; j++)
    {
        printf("%d :", j);
        for (  i=0; i<nlettre[j]; i++)
    {
          printf("_");
        }
      }
      return 0;
    }
    c'est un comble tt de meme , c'est l'exo 13 du livre le langage C norme ANSI de k&r , 2eme édition , et je compte bien savoir le faire un jour ou l'autre

    sur un exemple :

    salut jeune petit coq hi hi , le programme m'affiche ceci en résultat :

    9:

  12. #12
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    j'ai oublié la ligne nlettre[j] = 0; juste après le 1er for , erreur de frappe .

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Bibouda
    mdr , merci , voici le code final , et il ne marche pas , çà fait 2 semaines que je demande de l'aide sur internet , PERSONNE n'a trouvé la solution , c'est incroyable , ingénieur , débutant , étudiant , tt le monde se plante lol :
    On t'a dit d'initialiser les compteurs à 0.
    Citation Envoyé par Medinoc
    Il faut initialiser ton tableau à zéro avant. Sinon, il peut contenir n'importe quoi.
    C'est fait où ? Facile de critiquer les autres quand on écoute pas les conseils...

    Ton programme je l'ai corrigé chez moi en 5 minutes,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    salut jeune petit coq hi hi
    ^Z
    0 :
    1 :
    2 :__
    3 :_
    4 :
    5 :___
    6 :
    7 :
    8 :
    et depuis, j'essaye de te mettre sur la voie, mais visiblement, tu n'y comprends rien.

    Encore une piste. Pourque l'affichage soit lisible, il faut mettre un '\n' en fin de ligne. Il va te falloir encore 3 jours pour trouver le bon endroit ?

    Enfin, comme tu peux le voir, l'affichage se fait de 0 à 8. Normal, vu le codage de la boucle. Il faut mettre < 10 et non < 9...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Maitre corbeau sur un arbre perché, tenait en son bec un fromage.
    Maitre renard, par l'odeur alléché, lui tint à peu près ce langage
    ^Z
    0 :
    1 :_
    2 :____
    3 :______
    4 :__
    5 :_
    6 :___
    7 :_____
    8 :__
    9 :
    Pas de Wi-Fi à la maison : CPL

  14. #14
    Provisoirement toléré
    Inscrit en
    Octobre 2002
    Messages
    214
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 214
    Points : 33
    Points
    33
    Par défaut
    emmanuel ne le prends pas mal je critique pas , et je te remercie de m'aider , c'est juste que j'ai un peu les nerfs à vif tellement j'ai galéré pour ce code , vu le cours pourri que je me suis tapé sur les tableaux avec ce livre , çà n'a pas été évident , donc je te remercie pour tout .
    Jai demandé à un kernel hacker de chez freebsd de m'écrire le code en C , voici ce qu'il m'a proposé , et çà marche très bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
     
    int main(void)
    {
      int a, i, j;;
      int nlettre[9];
      int nl = 0;
     
    for ( i = 0; i < 9; i++)
    nlettre[i] = 0;
     
      while ( ( a = getchar() ) != EOF && nl < 10)
    {
        if ( (a == ' ' || a == '\n' || a == '\t' ) && nl > 0 && nl < 10 )
      {
      nlettre[nl-1]++;
          nl=0;
      }
        else
      {
          nl++;
      }
     
      for ( j = 0; j < 9; j++)
    {
        printf("%d :", j+1);
        for (  i=0; i<nlettre[j]; i++)
        {
          printf("_");
        }
          printf("\n");
      }
      return 0;
    }
    je relierai ce code au calme et j'essayerai de le commenter entièrement tout seul ( bien que j'ai déjà eu de l'aide de sa part ) , et si tu veux tu pourras juger tes commentaires , mais ne vois rien contre toi emmanuel , c'est que j'essaye de progresser mais malheuresement j'ai pas tjs un cours super détaillé sous les yeux , merci de ton aide .

  15. #15
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Un histogramme, c'est quand même plus joli verticalement...
    Je me suis aussi permis de rajouter un contrôle en cas de dépassement de tableau (mots de 10 lettres et plus, je les range dans la dernière catégorie).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    #include <stdio.h>
     
    int main(void)
    {
    	int a, i, j;
    	int nlettre[10];
    	int nl = 0;
    	int histomax = -1;
    	int hauteur;
     
    	for(j=0; j<10; j++)
    	{
    		nlettre[j] = 0;
    	}
     
    	while(( a = getchar() ) != EOF)
    	{
    		if(a == ' ' || a == '\n' || a == '\t')
    		{
    			if(nl > 9) nl = 9;
    			nlettre[nl]++;
    			nl=0;
    		}
    		else
    		{
    			nl++;
    		}
    	}
     
        for(j=1; j<10; j++)
    	{
    		if(histomax < nlettre[j])
    		{
    			histomax = nlettre[j];
    		}
    	}
     
    	hauteur = histomax;
    	while (hauteur)
    	{
    		for(j=1; j<10; j++)
    		{
    			if(nlettre[j] >= hauteur)
    			{
    				printf("X");
    			}
    			else
    			{
    				printf(" ");
    			}
    		}
    		printf("\n");
    		hauteur--;
    	}
     
    	for(j=1; j<10; j++)
    	{
    		printf("%d", j);
    	}
        printf("\n");
     
    	return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $ knr
    a ab ab abc abc abc abcd abcd abcde
      X
     XXX
    XXXXX
    123456789
    Bon, d'accord c'est pas très joli à regarder...

  16. #16
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par DaZumba
    Bon, d'accord c'est pas très joli à regarder...
    Essaye '*' ou '|' au lieu de 'X'...
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. hash MD5 en C, pas facile !
    Par jack_x4 dans le forum C
    Réponses: 14
    Dernier message: 08/03/2009, 08h14
  2. Réponses: 1
    Dernier message: 09/02/2007, 16h03
  3. [Joomla!] Joomla Pas Facile
    Par sandytarit dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 03/02/2007, 20h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo