Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercices pour débutants en C

Au menu : zSommeChiffres (nombres, algo)

18 mars 2009 à 18:42:28

Citation : May_Hop

Mais ne serait-il pas mieux de poster les codes (en secret) ? Ca permettrait de s'entraider et de recevoir des conseils sur la façon dont on code. De plus lire les codes des autres est aussi une façon de s'entrainer.

J'y avais egalement pensé et l'idée me paraît assez bonne (après seul à Eusebus et ShareMan d'en décider)
  • Partager sur Facebook
  • Partager sur Twitter
19 mars 2009 à 12:09:29

Pas bien dur comme exercice =)

Note: je défie quiquonque d'avoir un code plus simple que le mien sachant que les lettres doivent se printer par ordre alphabétique (sinon y a plus rapide en effet) :p :

#include <stdio.h>
#include <string.h>

/* tolower() si chaine non dure, mais là flemme. */

int main(void)
{
    char const chaine[] = "aaaaakeryzetzaafdsfgdfhcvcfoiepajdpsfaafg";
    size_t i = 0, j = 0;
    int c = 0, count = 0, size = 0;

    size = strlen(chaine);

    for(i = 0; i < 26; i++)
    {
        c = 'a' + i;

        for(j = 0; j < size; j++)
        {
            if(chaine[j] == c)
            count++;
        }

        if(count > 0)
        printf("%c-> %d (%d%%)\n", c, count, (count*100)/size);

        count = 0;
    }

    return 0;
}
  • Partager sur Facebook
  • Partager sur Twitter
19 mars 2009 à 13:48:05

A la compilation, j'obtiens déjà un

C:\...\Prog\temp\main.c||In function `main':|
C:\...\Prog\temp\main.c|18|warning: comparison between signed and unsigned|
||=== Build finished: 0 errors, 1 warnings ===|


Ensuite, tu ne gères ni les chiffres, ni les majuscules, il manque quelques petits trucs... ;)

Enfin, rien n'indique que la valeur des caractères de l'alphabet latin doivent se suivre... Si tu tombes sur un encodage bizarre, ton programme ne marchera pas.

Sinon c'est effectivement une manière simple de traîter le problème avec 1/.
Et si vous trouvez que l'exercice est trop simple, rien ne vous empêche de le complexifier, en vous aidant si vous le voulez des quelques pistes proposées.

Pour ma part j'ai fait un code avec gestion des accents, lecture dans un fichier d'un texte, classement des statistiques par ordre décroissant et choix d'inscrire les statistiques en console ou dans un fichier texte.

Sinon pour répondre aux autres questions, je pense que poster son code ici n'est pas forcément une bonne solution parce que les gens qui veulent résoudre l'exercice sont tentés de lire le code sans pour autant avoir vraiment réfléchi à comment ils feraient eux. Et ça permet aussi d'avoir une organisation plus carrée, il n'y a pas à chercher partout dans le topic le code d'un tel ou d'une telle. :)
  • Partager sur Facebook
  • Partager sur Twitter
19 mars 2009 à 15:55:32

Citation : Gambit2099

Je défie quiquonque d'avoir un code plus simple que le mien sachant que les lettres doivent se printer par ordre alphabétique (sinon y a plus rapide en effet) :p :



#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int c, i, freqs[256] = {0};
    
    while ((c = tolower(getchar())) != EOF)
        if (isalpha(c))
            freqs[c]++;

    for (i = 0; i < 256; ++i)
        if (freqs[i] > 0)
            printf("'%c'\t%d\n", i, freqs[i]);

    return 0;
}


Au passage, lire dans stdin est beaucoup plus flexible que lire une chaîne "en dur" ou lire dans un fichier, puisque l'utilisateur peut ensuite simplement utiliser des redirections et lire dans des fichiers, depuis des pipes, etc. En plus d'être plus simple, ça me semble clairement être une meilleure solution.
  • Partager sur Facebook
  • Partager sur Twitter
19 mars 2009 à 16:34:03

Citation : Eusebus

A la compilation, j'obtiens déjà un

C:\...\Prog\temp\main.c||In function `main':|
C:\...\Prog\temp\main.c|18|warning: comparison between signed and unsigned|
||=== Build finished: 0 errors, 1 warnings ===|


Mwoui, pas très important je réglerai ça. Sinon pour les ajouts, je trouve ça chiant les chiffres et compagnie (bien que bluestorm ait mis tout le monde d'accord... :p ).


Citation : Pas de titre

En plus d'être plus simple, ça me semble clairement être une meilleure solution.


Complètement oui.
  • Partager sur Facebook
  • Partager sur Twitter
19 mars 2009 à 23:43:05

Salut :)
J'ai une petite question : Pour faire les pourcentages d'occurences des lettres et des chiffres, on a le nombre d'ocuurence de cette lettre (ou de ce chiffre) par rapport aux nombre total de caractères de la chaine avec les espaces ou sans espaces ?
Autrement dit :
pourcentage = (nombreOccurences / strlen(chaine)) * 100;

Ou bien :
pourcentage = (nombreOccurences / myStrlen(chaine)) * 100;
// myStrlen() étant une fonction qui compte seulement le nombre des lettres et des chiffres (sans espaces)
  • Partager sur Facebook
  • Partager sur Twitter
20 mars 2009 à 0:01:52

A priori je dirais 2e solution, pour avoir un total de 100%, vu qu'on ne prend pas en compte les espaces. :)
  • Partager sur Facebook
  • Partager sur Twitter
24 mars 2009 à 0:43:31

je suis noveau sur le forum mon niveau en c /*les prototyp*/
  • Partager sur Facebook
  • Partager sur Twitter
24 mars 2009 à 14:26:18

Je crois qu'il est pas habitué des forums, il a posté le même message ailleurs...
  • Partager sur Facebook
  • Partager sur Twitter
24 mars 2009 à 17:09:23

Bonjour, avant tout je félicite Eusebus pour cet exercice.
Pour ceux qui veulent voir ma solution : http://membres.lycos.fr/windoweb/SDZ/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char car;
    //La méthode et assez barbare mais rien ne dit que les caractères alphabétique son successive sur toutes les machines.
    //Si vous avez une autre méthode faite le nous savoir.
    char tabAlph [26*2] ={'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',
                          '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'};
    char tabChif [10] ={'0','1','2','3','4','5','6','7','8','9'};
    int tabOccurAlph [26*2] ={0};
    int tabOccurChif [10] ={0};
    int i;

    //Ouvrir le fichie "Document texte.txt".
    FILE* fichier = NULL;
    fichier =fopen("Document texte.txt","r");

    if (fichier!= NULL)
    {
        do //Parcourir le fichier caractére par caractére.
        {
            car = fgetc(fichier);
            //Compter le nombre d'occurence des lettres de a..z & A..Z.
            for(i=1; i <= (26*2); i++)
            {
                if(car==tabAlph[i-1])
                {
                    tabOccurAlph[i-1]++;
                }
            }
            //Compter le nombre d'occurence des chiffres de 0..9.
            for(i=1; i <= 10; i++)
            {
                if(car== tabChif[i-1])
                {
                    tabOccurChif[i-1]++;
                }
            }

        }while(car!= EOF);

        fclose(fichier); //Fermer le fichier.
    }
    else //Affichage d'un message d'erreur si le fichier ne s'ouvre pas.
    {
       printf("Erreur de lecture du fichier.\n");
    }

    //Affichage des résulatats.
    printf("Statistiques du fichie :\n");
        //Nombre d'occurence des lettres de l'alphabet.
        for(i=1; i <= (26*2); i++)
        {
            if( tabOccurAlph[i-1]!=0)//Si le nombre d'occurence de la lettre est egale a 0 on affiche pas.
            {
               printf("[%c]: %i\n",tabAlph[i-1], tabOccurAlph[i-1]);
            }
        }
        //Nombre d'occurence des chiffres.
        for(i=1; i <= 10; i++)
        {
            if( tabOccurChif[i-1]!=0)//Si le nombre d'occurence du chiffre est egale a 0 on affiche pas.
            {
               printf("[%c]: %i\n",tabChif[i-1], tabOccurChif[i-1]);
            }
        }

    system("pause");
    return 0;
}
  • Partager sur Facebook
  • Partager sur Twitter
28 mars 2009 à 10:03:15

C'est bien compliqué dis donc ^^ Puis il manque plein de caracteres... Ya plus simple qu'un tableau
  • Partager sur Facebook
  • Partager sur Twitter
30 mars 2009 à 17:25:23

Bluestorm a donné la meilleure solution en O(N).
Vous pouvez essayez de retrouver les fréquences d'Al Kindi des textes français avec votre programme, c'est à dire la fréquence d'apparition de chaque lettre, pour embeter César.
  • Partager sur Facebook
  • Partager sur Twitter
1 avril 2009 à 19:48:13

Voici ma solution:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#define    BUF_SIZE    256

int main(void) {
    /* Init. */
    size_t i = 0;
    size_t count = 0;
    short int cur_c = 0;
    short int stats[BUF_SIZE] = {0};
    
    /* Operate. */
    while((cur_c = tolower(getchar())) != '\n') {
        if(isalnum(cur_c)) {
            stats[cur_c]++;
            count++;
        }
    }

    for(i = 0; i < BUF_SIZE; i++) {
        if(stats[i] > 0) {
            printf("%c%4d%8.2f%%\n", i, stats[i], (float)stats[i]/(float)count*100);
        }
    }

    /* Conclude. */
    return EXIT_SUCCESS;
}

hoffa@hoffa-laptop:~/Foobar$ ./a.out
I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones.
3   1    1.18%
4   1    1.18%
6   2    2.35%
8   2    2.35%
a   6    7.06%
b   4    4.71%
c   1    1.18%
d   2    2.35%
e   8    9.41%
f   3    3.53%
g   4    4.71%
h   1    1.18%
i   6    7.06%
j   1    1.18%
k   1    1.18%
l   3    3.53%
m   2    2.35%
n   7    8.24%
o   8    9.41%
p   2    2.35%
r   4    4.71%
s   6    7.06%
t   5    5.88%
u   2    2.35%
w   1    1.18%
y   2    2.35%

  • Partager sur Facebook
  • Partager sur Twitter
4 avril 2009 à 20:35:01

Voila la mienne pour le 1/

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s[] = "boku wa kira";
    int count[26] = {0};
    unsigned int i = 0;

    for (; i < strlen(s); i++)
        count[s[i] - 97]++;

    for (i = 0; i < 26; i++)
    {
        if (count[i])
        {
            char c = i + 97;
            printf("%c : %d \n", c, count[i]);
        }
    }

    return (0);
}


a : 2
b : 1
i : 1
k : 2
o : 1
r : 1
u : 1
w : 1
  • Partager sur Facebook
  • Partager sur Twitter
7 avril 2009 à 7:20:01

noob4ever :
for (; i < strlen(s); i++)

Je te déconseille d'appeler strlen dans la boucle car du coup à chaque tour de boucle tu recalcules la taille de s : perte de temps inutile. Mieux vaut que tu calcules une fois seulement au début la taille de s que tu stockes dans une variable. ;)
  • Partager sur Facebook
  • Partager sur Twitter
7 avril 2009 à 11:42:27

Citation : May_Hop

noob4ever :

for (; i < strlen(s); i++)


Je te déconseille d'appeler strlen dans la boucle car du coup à chaque tour de boucle tu recalcules la taille de s : perte de temps inutile. Mieux vaut que tu calcules une fois seulement au début la taille de s que tu stockes dans une variable. ;)


C'est juste, mais comme c'est celui qui fait le code le plus court qui a la plus grosse.... :D
  • Partager sur Facebook
  • Partager sur Twitter
7 avril 2009 à 20:29:25

@noob4ever : je n'ai pas compris le sens de ta phrase.

Tu peux très bien faire ceci.
for (int tailles = strlen(s); i < tailles; i++)
cela revient au même sauf que strlen est évalué qu'une seule fois.
  • Partager sur Facebook
  • Partager sur Twitter
7 avril 2009 à 20:31:01

Citation : Jaloyan1

@noob4ever : je n'ai pas compris le sens de ta phrase.

Tu peux très bien faire ceci.
for (int tailles = strlen(s); i < tailles; i++)
cela revient au même sauf que strlen est évalué qu'une seule fois.


Interdit en C90. C'est possible uniquement en C99.
  • Partager sur Facebook
  • Partager sur Twitter
7 avril 2009 à 20:39:30

Citation : Miphys

Citation : Jaloyan1

@noob4ever : je n'ai pas compris le sens de ta phrase.

Tu peux très bien faire ceci.
for (int tailles = strlen(s); i < tailles; i++)
cela revient au même sauf que strlen est évalué qu'une seule fois.


Interdit en C90. C'est possible uniquement en C99.



En effet, mais étant donné que mon compilateur est programmé pour le C99, c'est normal que cela m'a échappé.
Désolé de l'erreur(il suffit juste de corriger en déclarant juste avant le for, c'est pas si grave).
  • Partager sur Facebook
  • Partager sur Twitter
8 avril 2009 à 10:36:14

Citation : Pas de titre

En effet, mais étant donné que mon compilateur est programmé pour le C99


La honte. Aussi on dit pas "programmé" mais configuré.
  • Partager sur Facebook
  • Partager sur Twitter
8 avril 2009 à 12:52:14

Citation : noob4ever

C'est juste, mais comme c'est celui qui fait le code le plus court qui a la plus grosse....


J'ose espérer que ceci n'est qu'une blague :D Sinon tu mérites ton pseudo :-°
  • Partager sur Facebook
  • Partager sur Twitter
8 avril 2009 à 14:47:55

Citation : May_Hop

Citation : noob4ever

C'est juste, mais comme c'est celui qui fait le code le plus court qui a la plus grosse....


J'ose espérer que ceci n'est qu'une blague :D


Si tel n'est pas le cas je plains sincèrement "idir" :lol:
  • Partager sur Facebook
  • Partager sur Twitter
8 avril 2009 à 15:02:34

Citation : May_Hop

Citation : noob4ever

C'est juste, mais comme c'est celui qui fait le code le plus court qui a la plus grosse....


J'ose espérer que ceci n'est qu'une blague :D


C'était à mon avis un sarcasme... Voir un peu plus haut:

Citation : bluestorm

Citation : Gambit2099

Je défie quiquonque d'avoir un code plus simple que le mien sachant que les lettres doivent se printer par ordre alphabétique (sinon y a plus rapide en effet) :p :



#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int c, i, freqs[256] = {0};
    
    while ((c = tolower(getchar())) != EOF)
        if (isalpha(c))
            freqs[c]++;

    for (i = 0; i < 256; ++i)
        if (freqs[i] > 0)
            printf("'%c'\t%d\n", i, freqs[i]);

    return 0;
}


Et puis tu n'as pas besoin d'une ligne de plus hein:
#include <stdio.h>
#include <string.h>

int main(void)
{
    char s[] = "boku wa kira";
    int count[26] = {0};
    unsigned int i = 0, size = strlen(s);

    for (; i < size; i++)
        count[s[i] - 97]++;

    for (i = 0; i < 26; i++)
    {
        if (count[i])
        {
            char c = i + 97;
            printf("%c : %d \n", c, count[i]);
        }
    }

    return (0);
}

edit: suite à la remarque de Monsieur_JaKy, je n'avais pas fait attention désolé.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
8 avril 2009 à 21:22:04

C'est un exercice plutôt simple, à la portée des débutants; ce serait bien de ne pas balancer des solutions...faudrait les forcer à réfléchir un peu...
  • Partager sur Facebook
  • Partager sur Twitter
9 avril 2009 à 13:12:30

Personne ne force les débutants à faire les exercices. Soit ils veulent s'entraîner et ils les font sans pomper, soit il ne veulent pas, et ne les font pas (donc plus question de pomper).
  • Partager sur Facebook
  • Partager sur Twitter
9 avril 2009 à 21:11:31

Citation : ShareMan

Titre : zGame
mois : Janvier
Sujet : Révisions du cours de M@teo21

L'exercice !



L'exercice de ce mois-ci sera : un jeu : zGame !
Ce jeu sera d'un niveau simple afin qu'un maximum de débutants en C puissent le coder. Il est dans le même style que le jeu du pendu proposé par M@teo21 ici (lien). Il va vous permettre de pratiquer, mais pas contre, il n'y a pas de thème bien particulier, vous allez devoir réutiliser quasiment tout ce que vous savez (variables, conditions, boucles, nombres pseudo-aléatoires, calculs, etc.).

En plus, vous ne perdez rien, en vous entraînant, vous réalisez un jeu amusant et utile ! :) Let's go.

Le but du jeu



zGame est un grand classique parmi les jeux que l'on réalise pour s'entraîner.

Le programme vous tire une série de dix calculs mathématiques sur les tables de multiplication (oui, ceux qu'on bosse en primaire ^^ ). Le but du jeu est de trouver la bonne réponse à ces calculs le plus rapidement possible et en faisant le moins d'erreurs possibles.

À quoi doit ressembler votre programme ?



Le programme .. c'est à vous de le faire. :p
Vous allez donc commencer par afficher le nom du jeu (j'ai pris zGame, mais vous le nommez comme vous voulez) ainsi qu'une rapide présentation des règles. Ensuite, vous soumettez le joueur (l'utilisateur de votre programme) à une série de dix calculs comportant obligatoirement que 2 facteurs (un facteur, c'est l'un des termes d'une multiplication). Ces facteurs doivent obligatoirement être des nombres entiers compris entre 0 et 10, les deux inclus, et tirés pseudo-aléatoirement !

À la fin de cette série de calculs, vous affichez le temps total qu'a mis le joueur pour trouver les réponses (c'est parfois amusant ^^ ) ainsi que le nombre d'erreurs qu'il a pu faire.

On peut par exemple imaginer ceci :

-zGame- : Entraînez votre cerveau au calcul mental !

 Le programme va vous soumettre dix calculs sur les tables de multiplication,
 calculs que vous allez devoir résoudre le plus rapidement possible et ... de tête !

Près ? Appuyez sur entrer pour commencer...

 5*9 = 45
 3*4 =
 [...]

Vous avez mis 15.234 seconde(s) et vous avez 1 erreur(s) !
Appuyez sur entrer pour quitter...



Pour le calcul du temps qu'a mis le joueur à résoudre la série des dix calculs, jetez un oeil à la correction de zTri (lien). Pour le tirage des valeurs pseudo-aléatoires, j'utilise rand()%11 ce qui tire une valeur entre 0 et 10, les deux inclues. Je vous conseille aussi de lire le tutoriel de Natim sur les nombres aléatoires (lien).

Je crois que vous avez suffisamment d'informations, maintenant, c'est à vous de coder ! Au boulot ! :p

Je posterai la correction dans trois semaines. Je donnerai plus de détails sur cette date dés que possible.

Have a lot of fun !

crys


Pour réaliser ceci même pas besoin de connaître le C.
Je connais le Php et je débute en C , j'ai lu quelques chapitres de C et c'est vraiment facile.
Il faudrait trouver des exercices moyen, car ou bien on trouve des exercices trop difficile pour un débutant soit trop facile. Sinon c'est une bonne idée de faire des exercices ;) .
  • Partager sur Facebook
  • Partager sur Twitter
9 avril 2009 à 21:15:31

Le truc c'est qu'il faut que ça soit accessible quand même, et certains peuvent galérer sur des choses qui peuvent nous sembler facile.

C'est là toute la difficulté de trouver un exo correct, d'ailleurs j'avoue que là je cherche mais pas facile pour essayer de contenter le max de monde. Donc si vous avez des trucs sur lesquels vous voudriez vous entraîner (j'sais pas, genre structures, algos, manipulation de fichiers, etc...) allez-y, le topic est aussi fait pour ça. Un bon exercice est un exercice où les gens seront motivés, et qui mieux que vous connait ce qui vous intéresse le plus dans un exercice ? :)
  • Partager sur Facebook
  • Partager sur Twitter
9 avril 2009 à 21:19:13

Citation : Eusebus

Le truc c'est qu'il faut que ça soit accessible quand même, et certains peuvent galérer sur des choses qui peuvent nous sembler facile.

C'est là tote la difficulté de trouver un exo correct, d'ailleurs j'avoue que là je cherche mais pas facle pour essayer de contenter le max de monde. Donc si vous avez des trucs sur lesquels vous voudriez vous entraînez (j'sais pas, genre structures, algos, manipulation de fichiers, etc...) allez-y, le topic est aussi fait pour ça. Un bon exercice est un exercice où les gens seront motivés, et qui mieux que vous connait ce qui vous intéresse le plus dans un exercice ? :)

A mon avis un exercice motivant pour avancés serait un chat en ligne. Tu choisis un pseudo et tu peux commencer a chatter.
  • Partager sur Facebook
  • Partager sur Twitter
10 avril 2009 à 7:18:55

Euh, ça ce n'est vraiment pas pour les débutants ... En plus de devoir bien connaître les bases de la programmation en C, il faut connaître les sockets, les threads ... Avoir quelques notions en réseau. Et c'est assez gros comme code pour un débutant.
Après tu dis pour les avancés mais bon est-ce vraiment le but de ce topic ?
  • Partager sur Facebook
  • Partager sur Twitter