Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercices pour débutants en C

Au menu : zSommeChiffres (nombres, algo)

2 février 2010 à 11:37:14

Citation : darkipod

bonjour,
j'ai fait les premiers exos du mois de fevrier




Merci de poster sa solution au bon endroit, je te rappelle ce qu'a proposé l'auteur de l'exercice de février :



Citation : GurneyH

Un sujet est ouvert ici pour poster les réponses.




  • Partager sur Facebook
  • Partager sur Twitter
2 février 2010 à 11:43:39

merci,je transfère ma reponse
  • Partager sur Facebook
  • Partager sur Twitter
Team OC 3 février 2010 à 2:27:16

Je remercie l'auteur de maintenir en place ce topic. Pour moi, qui ai décidé d'apprendre à programmer en C/C++ (et je pars de 0) c'est vraiment rassurant d'avoir des gens compétents vers qui se tourner en cas de souci.

Merci! :)
  • Partager sur Facebook
  • Partager sur Twitter
C'est pas intéressant quand ça marche, mais quand ça ne marche pas !
3 février 2010 à 18:18:39

Bonjour à tous,

Voici ma solution de zReader d'octobre 2008.
Mon code est-il bon ?

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

#define TAILLE_MAX 100

int main()
{
    int choix = 0;

    FILE *fichier = NULL;

    char chaine[TAILLE_MAX] = "";

    char nomFichier[TAILLE_MAX] = "";

    int i = 0; //Pour le case 1 du switch

    while((choix < 1) || (choix > 3))
    {
        printf("\nBonjour, faites votre choix:\n\n");

        printf("1. Lire un fichier\n");
        printf("2. Creer un fichier\n");
        printf("3. Ecrire dans un fichier\n\n");

        printf("Votre choix ? ");

        scanf("%d", &choix);
    }

    switch(choix)
    {
    case 1:

        fichier = fopen("test.txt", "r");
        if (fichier != NULL)
        {
            while(fgets(chaine, TAILLE_MAX, fichier) != NULL)
            {
                printf("%s", chaine);
            }
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("Impossible d'ouvrir le fichier test.txt");
        }

    break;

    case 2:

        printf("Entrez le nom du fichier avec son extension:\n");
        scanf("%s", nomFichier);

        fichier = fopen(nomFichier, "w");
        if (fichier != NULL)
        {
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("Impossible de creer le fichier %s\n", nomFichier);
        }

    break;

    case 3:

        fichier = fopen("test2.txt", "w+");
        if (fichier != NULL)
        {
            printf("Entrez une phrase a ecrire:\n");
            scanf("%s", chaine);
            fprintf(fichier, chaine);
        }
        else
        {
            // On affiche un message d'erreur si on veut
            printf("Impossible d'ecrire dans le fichier test2.txt");
        }

    break;

    default:
    break;
    }

    fclose(fichier);

    system("PAUSE");
    return 0;
}


Merci d'avance pour vos réponses... :)
  • Partager sur Facebook
  • Partager sur Twitter
4 février 2010 à 15:41:57

Voici mon code. Le temps estimé pour trouver le nombre de nombre dont la somme des chiffres est égale à 27 compris entre 0 et 1 000 000 000 est de 340s (34s pour 100 000 000). Mon algo n'est donc pas optimisé.
#include <stdio.h>
#include <stdlib.h>

int zSommeChiffres(int n);
int combien(int MAX, int S);

int main(void)
{
    int n1 = 92538;
    int MAX = 100000000, S = 27;
    printf("%d -> %d\n", n1, zSommeChiffres(n1));
    printf("Entre 0 et %d, combien de nombres\n"
           "ont la somme de leurs chiffres egale a %d ? %d", MAX, S, combien(MAX, S));

    return 0;
}

int combien(int MAX, int S)
{
    int i = 0, s = 0;
    for (i = 0; i <= MAX; i++)
    {
        if (zSommeChiffres(i) == 27)
            s += 1;
    }
    return s;
}

int zSommeChiffres(int n)
{
    int s = 0, dizaineActuel = 100000000; // 1000000000 = 100 000 000   MAX = 999 999 999
    while (n >= 10)
    {
        if (n >= dizaineActuel)
        {
            s += n/dizaineActuel;
            n -= dizaineActuel * (n/dizaineActuel);
        }
        if (s > 27)
            n = 0;
        dizaineActuel /= 10;
    }
    s += n;
    return s;
}
  • Partager sur Facebook
  • Partager sur Twitter
"If debbugging is the process of removing bugs, then programming must be the process of putting them in." (Edsger Dijkstra)
4 février 2010 à 17:40:59

Tu t'embêtes beaucoup pour ta fonction zSommeChiifre
n -= dizaineActuel * (n/dizaineActuel);

Et heu, ta fonction combien n'est ok que pour s = 27, non?

Je ne comprend pas pourquoi tu as
if (s > 27)
    n = 0;
    dizaineActuel /= 10;

Dans ta fonctionzSommeChiifre
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
4 février 2010 à 18:21:38

int combien(int MAX, int S)
{
    int i = 0, s = 0;
    for (i = 0; i <= MAX; i++)
    {
        if (zSommeChiffres(i) == S) // je m'étais trompé
            s += 1;
    }
    return s;
}

int zSommeChiffres(int n)
{
    int s = 0, dizaineActuel = 100000000; // 1000000000 = 100 000 000   MAX = 999 999 999
    while (n >= 10)
    {
        if (n >= dizaineActuel) // par exemple au premier tour de boucle, dizaineActuel = 100000000
        {
            s += n/dizaineActuel; // je compte le nombre de dizaine de 100000000 que le nombre a. Si c'est 512323623, le nombre de dizaines de 100000000 sera 5.
            n -= dizaineActuel * (n/dizaineActuel); // j'enlève ses 5 dizaines de 100000000. Le nombre devient 12323623
        }
        /** if (s > 27) // C'était pour optimiser avec le chiffre mais bon ... si on change 27, ça ne marche plus.
            n = 0; **/
        dizaineActuel /= 10; // On enlève un 0 à 100000000 qui devient 10000000.
    }
    s += n;
    return s;
}
  • Partager sur Facebook
  • Partager sur Twitter
"If debbugging is the process of removing bugs, then programming must be the process of putting them in." (Edsger Dijkstra)
4 février 2010 à 20:31:55

@schadocalex :
Ta fonction zSommeChiffres n'est vraiment pas optimale, en plus on ne peut pas lui envoyer un nombre supérieur à 999 999 999. alors qu'avec un autre algorithme on a aucune limitation et la fonction tient sur 4 lignes.

Un indice :
Utilise le modulo (%) de 10 pour extraire le premier chiffres puis divise par 10 le nombre sur lequel tu travaille.
  • Partager sur Facebook
  • Partager sur Twitter
4 février 2010 à 20:53:19

Tu veux dire comme ça :
int zSommeChiffres(int n)
{
    int s = 0;
    while (n != 0)
    {
        s+=n%10;
        n/=10;
    }
    return s;
}


Tu as raison, plus que 6 secondes :p

Avec mon optimisation ( if (S) if(s>S) n = 0; ), je gagne 10s et je passe à 65s pour 1000000000

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

int zSommeChiffres(int n, int S);
int combien(int MAX, int S);

int main(void)
{
    int n1 = 92538;
    int MAX = 1000000000, S = 27;
    printf("%d -> %d\n", n1, zSommeChiffres(n1, 0));
    printf("Entre 0 et %d, combien de nombres\n"
           "ont la somme de leurs chiffres egale a %d ? %d", MAX, S, combien(MAX, S));

    return 0;
}

int combien(int MAX, int S)
{
    int i = 0, s = 0;
    for (i = 0; i <= MAX; i++)
    {
        if (zSommeChiffres(i, S) == S)
            s += 1;
    }
    return s;
}

int zSommeChiffres(int n, int S)
{
    int s = 0;
    while (n != 0)
    {
        s+=n%10;
        n/=10;
        if (S)
        if(s>S)
            n = 0;
    }
    return s;
}


Trop compliqué pour moi je retourne à mon MMORPG :-° (j'rigole ^^)
  • Partager sur Facebook
  • Partager sur Twitter
"If debbugging is the process of removing bugs, then programming must be the process of putting them in." (Edsger Dijkstra)
4 février 2010 à 21:40:25

Citation : schadocalex

Tu veux dire comme ça :

int zSommeChiffres(int n)
{
    int s = 0;
    while (n != 0)
    {
        s+=n%10;
        n/=10;
    }
    return s;
}



Oui, c'est à ça que je pensais bien qu'une boucle for serais plus appropriée.
int
zSommeChiffres(int n) {
    int sum;
    for (sum = 0 ; n > 0 ; n /= 10)
        sum += n%10;
    return sum;
}
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:07:03

J'ai fini! :D
(Même si l'algo pour trouver les nombre est pas très optimisée)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>//Pour utiliser strlen



int zSommeChiffres(unsigned int n);
int zSommeChiffresChar(char src[]);
int sommeEgale (unsigned int max, unsigned int somme);



int main(int argc, char *argv[])
{
    unsigned int nombre = 0, max = 0, somme = 0;
    char nombreChar[100] = {0};

    printf ("Entrez un nombre entre 0 et 4 294 967 295 : ");//On demande le nombre
    scanf("%d", &nombre);
    printf("La somme des chiffres de %d est %d\n\n\n", nombre, zSommeChiffres(nombre));//On affiche le nombre int et on fait la somme (appel de la fonction)

    printf("Entrez un nombre entre 0 et 10 puissance 100 : ");
    scanf("%s", nombreChar);
    printf("La somme des chiffres de \n%s est %d\n\n\n", nombreChar, zSommeChiffresChar(nombreChar));

    printf("Choisissez deux nombres : ");
    scanf("%d", &max);
    printf(" et ");
    scanf("%d", &somme);
    printf("\nIl y a %d nombre entre 0 et %d dont la somme des chiffres est %d\n", sommeEgale(max, somme), max, somme);
    return 0;
}


int zSommeChiffres(unsigned int n)
{
    int  i = 0;
    int somme = 0;

    for (i = 0; i<12; i++)
    {
    somme += n % 10;//On récupère le chiffre des unités et on le rajoute
    n /= 10;//On vire le chiffre des unités et celui des dizaines devient les unités
    }

    return somme;
}



int zSommeChiffresChar(char src[])
{
    unsigned int tailleChaine = 0, somme = 0;
    int i = 0;

    tailleChaine = strlen(src);//Pour eviter de faire 100 tours de boucle pour rien

    for (i = 0; i < tailleChaine; i++)//Conversion ASCII/nombres et ajout à somme
    {
        switch (src[i])
        {
            case '0':
            somme += 0;
            break;

            case '1':
            somme += 1;
            break;

            case '2':
            somme += 2;
            break;

            case '3':
            somme += 3;
            break;

            case '4':
            somme += 4;
            break;

            case '5':
            somme +=5;
            break;

            case '6':
            somme += 6;
            break;

            case '7':
            somme += 7;
            break;

            case '8':
            somme += 8;
            break;

            case '9':
            somme += 9;
            break;

            default://Au cas où on aurait enré des lettres
            somme += 0;
            break;

            }
    }

    return somme;
}

int sommeEgale (unsigned int max, unsigned int somme)
{
    int nombreEgal = 0;
    unsigned int i = 0;

    for (i = 0; i <= max; i++)//On teste chaque nombre un par un
    {
        if (zSommeChiffres(i) == somme)//On fait la somme des chiffres de n. Si c'est la bonne...
        {
            nombreEgal ++;//...il y a un bon nombre de plus
        }
    }

    return nombreEgal;
}


J'ai nettement l'impression que je peut ameliorer la fonction qui calcule les chars...
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:09:38

'1' - '0' == 1

sers toi de ça
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:25:03

Ahah! J'ai compris:
int zSommeChiffresChar(char src[])
{
    unsigned int tailleChaine = 0, somme = 0;
    int i = 0;

    tailleChaine = strlen(src);//Pour eviter de faire 100 tours de boucle pour rien

    for (i = 0; i < tailleChaine; i++)//Conversion ASCII/nombres et ajout à somme
    {
        somme += src[i] - '0';
    }

    return somme;
}


D'ailleur, ce que tu a posté est faux: '1' - '0' = 1

Est-ce qu'il y a un moyen d'ameliorer l'algo de la fonction sommeEgale (precedant message)?
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:37:18

non ,c'est correct, tu peux pas avoir de lvalue non constante et tu peux pas assigner a une valeur constante (encore moins de la table ASCII)
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:40:04

Si on considère le = comme le signe mathématique, alors c'est correct ce qu'a écrit nasta.
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:41:29

oui mais si on considère l'expression comme mathématique, alors le '0' veut rien dire... et 1 - '0' veut rien dire non plus... donc bon, quitte a être logique, autant le rester jusqu'au bout
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:43:30

On va dire que tout le monde a juste selon le point de vue. :p
Peace and love
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:46:05

Citation : nasta

D'ailleur, ce que tu a posté est faux: '1' - '0' = 1


Pfff... N'importe quoi !
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 16:47:35

Citation

On va dire que tout le monde a juste selon le point de vue. :p
Peace and love



D'accord, on va juste dire que tu n'as pas le même point de vue que la majorité ;)

Citation


Pfff... N'importe quoi !

  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 17:08:09

Citation : Adroneus

oui mais si on considère l'expression comme mathématique, alors le '0' veut rien dire... et 1 - '0' veut rien dire non plus... donc bon, quitte a être logique, autant le rester jusqu'au bout


Juste le = ^^ .

Au pire nasta, on t'a dit que c'était faux car le signe égal en prog est un signe d'affectation.
//tu affectes la valeur 5 à n
int n = 5;

//en revanche tu ne peux pas faire
5 = n;

// les test se font de la manière suivante

if(n == 5); /*équivaut à */ if(5 == n);
  • Partager sur Facebook
  • Partager sur Twitter
6 février 2010 à 17:25:11

Citation : Colb-Seton




// les test se font de la manière suivante

if(n == 5); /*équivaut à */ if(5 == n);


Jamais été convaincu par cette pratique peu naturelle. En, plus un compilateur bien réglé t'avertit et enfin, parfois même si c'est rare, on affecte en même temps qu'on teste ie on est en situation d'écrire :

if (x=0)
{
/*  bla bla bla */
}


  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 13:09:00

Moi aussi je préfère la première façon pour le test ^^ .

Citation : candide

parfois même si c'est rare, on affecte en même temps qu'on teste ie on est en situation d'écrire :

if (x=0)
{
/*  bla bla bla */
}

Oui, maintenant je l'utilise quand je fais mon malloc (test et malloc en un) .
if(t = malloc(sizeof(n) *n))
    /*...*/

  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 13:13:39

malloc(sizeof(n) *n)

Tu devrais revoir l'utilisation de malloc... :-°

  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
7 février 2010 à 13:21:51

Citation : GurneyH

malloc(sizeof(n) *n)


Tu devrais revoir l'utilisation de malloc... :-°


J'aurais dû poster un peu plus de code :
int main(void)
{
    int n, i, *t;

    scanf("%d",&n);
    if(t = malloc(sizeof(n) *n))
        /*...*/
    return 0;
}
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 13:56:26

Mouais, et si n n'est pas du même type que t ?
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 14:12:34

Alors :
t = malloc(sizeof(t) *n);
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 15:10:37

Citation : Colb-Seton

Alors :

t = malloc(sizeof(t) *n);


Tu n'y es pas du tout.
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 15:26:49

Pourtant ça passe chez moi.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
7 février 2010 à 15:39:44

Change t en pointeur sur char pour voir ^^
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 15:48:17

Bah pareil ça passe sans warning sans rien, après c'est vrai j'ai pas réglé mon compilo.
  • Partager sur Facebook
  • Partager sur Twitter