Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercices pour débutants en C

Au menu : zSommeChiffres (nombres, algo)

7 février 2010 à 15:50:33

Que vaut sizeof t ?
Ca vaut la taille d'un pointeur (4 octets chez toi sûrement).

Que vaut sizeof *t ?
La taille pointée par t, çàd la taille d'un int.
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 15:54:54

Donc je dois changer mon t en *t dans le malloc ?
Donc si je comprends :
t = malloc(sizeof (*t) * n);
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 16:00:42

Note que j'ai pas mis de parenthèses. Les parenthèses ne sont utiles que pour les types (int, double etc.).
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 17:26:26

Citation : Colb-Seton

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



Le compilo te dira jamais rien pour ça, même en mode super-intégriste. Eventuellement un analyseur de code comme lint (mais bon, va pas te lancer là-dedans, commence par apprendre les choses basiques).
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 17:38:16

Citation : Pouet_forever

Note que j'ai pas mis de parenthèses. Les parenthèses ne sont utiles que pour les types (int, double etc.).


Ok je note :p .

Sinon dans mon malloc ce qui n'allait pas, c'est que c'était pas la bonne méthode pour être générique (si je vous suis).
  • Partager sur Facebook
  • Partager sur Twitter
7 février 2010 à 19:08:40

Citation : Colb-Seton


Sinon dans mon malloc ce qui n'allait pas, c'est que c'était pas la bonne méthode pour être générique (si je vous suis).



Oui et non. Le problème est qu'il ne faut pas bruler les étapes : as-tu vraiment besoin d'être générique ? Occasionnellement peut-être mais dans l'immensité des situations : non. Quand tu auras plus d'expérience et que tu auras dépassé certaines difficultés du langage alors tu pourras te permettre certaines "finasseries". Donc au début (et même au milieu ...), te prends pas la tête. Si tu veux malloquer 200 entiers, et bien écris ceci


int *t=malloc(200*sizeof(int));



Bien sûr, tu pourrais écrire :

int *t=malloc(200*sizeof *t);


mais franchement à quoi bon, dans l'immense majorité des cas, la première version suffira complètement.
  • Partager sur Facebook
  • Partager sur Twitter
8 février 2010 à 0:20:44

Bonsoir je suis toujours sur l'exo la somme des nombres.
Alors voila ma fonction sommeChiffre corrigé si quelqu'un peut me confirmé si c'est bon cet fois.
int zSommeChiffres(int n)
{
     int somme=0;

    while(n!=0)  //100/10=10/10=1  100%10=0 456%10=6 456/10=45  45%10=5 45/10=4 4%10=0 4/10=0  4560%10=0 4560/10=456
    {
        somme += n%10;
       printf("nMod10 = %ld\n",n%10);
        n /= 10;
        printf("n = %ld\n",n);
    };

    return somme;
}


Par contre les résultats seront eronné pour des entiers supérieur a 2147483647.

Je bloque par contre sur la dernier partie, en effet si je fait la fonction suivante:
int zSommeChiffresEgal(char *N,int S)
je souhaite faire l'algo suivant:
parcourir mon tableau 1 par 1 et a chaque fois faire la somme des nombres et testé si elle est egal a S.
Par contre la ou je bloque comment faire une boucle pour un nombre genre 1459784612340012340123478942651012315647894561230123456789, donc superieur a un int!
merci.


  • Partager sur Facebook
  • Partager sur Twitter
8 février 2010 à 9:24:11

Il faut utiliser les chaines de caractères pour le très long chiffre.

EDIT : mon message a été coupé :-°
  • 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)
8 février 2010 à 18:30:53

Citation : candide

Oui et non. Le problème est qu'il ne faut pas bruler les étapes : as-tu vraiment besoin d'être générique ? Occasionnellement peut-être mais dans l'immensité des situations : non. Quand tu auras plus d'expérience et que tu auras dépassé certaines difficultés du langage alors tu pourras te permettre certaines "finasseries". Donc au début (et même au milieu ...), te prends pas la tête. Si tu veux malloquer 200 entiers, et bien écris ceci


Mais est ce que ce n'est pas une bonne habitude à prendre ?
Comme par exemple essayer de faire portable, je pense notamment à :
getchar(); /*plutôt que */ system("PAUSE");

/*
 c'est portable et ça mange pas de pain,
 avec la généricité c'est pareil 
 (dans le cas du malloc en tout cas). 
*/
  • Partager sur Facebook
  • Partager sur Twitter
8 février 2010 à 20:53:56

@Colb-Seton:
Portabilité <math>\(\neq\)</math> Généricité

Produire un code portable est avantageux car tout le monde peut utiliser ton programme, alors que faire un code générique c'est produire un code qui travaille sans ce soucier du type de données.
En clair, la généricité devient utile que si tu souhaite créer une petite bibliothèque de fonctions, bien que tu puisse en avoir besoin pour d'autres raisons mais c'est assez rare.
  • Partager sur Facebook
  • Partager sur Twitter
8 février 2010 à 20:57:25

C'est une bonne habitude c'est vrai. Mais quand on n'est pas à l'aise avec les bases, pas la peine de se brouiller en utilisant quelque chose de plus générique juste parce que « c'est mieux ».
  • Partager sur Facebook
  • Partager sur Twitter
8 février 2010 à 22:28:42

Citation : Colb-Seton


Mais est ce que ce n'est pas une bonne habitude à prendre ?



La cerise sur le gâteau ne fait pas le pâtissier ...
  • Partager sur Facebook
  • Partager sur Twitter
13 février 2010 à 17:40:00

zArray1d : correction



exercice 1:


Les fonctions
int indexMin(int tableau[], int tailleTableau);
et
int indexMax(int tableau[], int tailleTableau);


Pour la fonction indexMin.
On parcourt le tableau en entier, et on garde trace de la position de plus petit élément rencontré jusqu'à présent.
Le principe est le même pour trouver l'index du maximum, et dans les 2 cas, on aura effectué tailleTableau - 1 comparaisons.
/* Exercice 1---------------------------------------------------------------- */
int indexMin(int tableau[], int tailleTableau)
{
    int i;
    int iMin = 0;

    for (i = 1; i < tailleTableau; i++)
        if (tableau[i] < tableau[iMin])
            iMin = i;

    return iMin;
}

int indexMax(int tableau[], int tailleTableau)
{
    int i;
    int iMax = 0;

    for (i = 1; i < tailleTableau; i++)
        if (tableau[i] > tableau[iMax])
            iMax = i;

    return iMax;
}


Exercice 2


La fonction
void afficherEltCommuns(int tableau[], int tailleTableau);


Beaucoup se sont contentés de faire une double boucle, et d'afficher l'élément si il était présent dans les 2 tableaux. C'était un peu plus compliqué, et l'énoncé, n'était probablement pas clair. :-°
Prenons les tableaux :
{0, 1, 10, 11, 10, 10};
{10, 1, 11, 7, 98, 8, 7, 10};

Si on met en valeur les éléments communs, on obtient :
{0, 1, 10, 11, 10, 10};
{10, 1, 11, 7, 98, 8, 7, 10};
Le dernier 10 du premier tableau, n'a plus de double dans le second tableau.
Les éléments communs sont :
[1, 10, 11, 10]

Il y avait plusieurs possibilités :
  • On pouvait avoir un tableau supplémentaire de la taille d'un des 2 tableau et marquer les éléments déjà rencontrés pour ne pas les sélectionner une deuxième fois.
  • Supprimer l'élément dans l'un des 2 tableaux, une fois sélectionné.

J'ai choisi la seconde possibilité.

Comment supprimer simplement un élément dans un tableau?
Soit à supprimer le second élément du tableau suivant

{10, 1, 11, 7, 98, 8, 7, 10};
On l'échange avec le dernier élément
{10, 10, 11, 7, 98, 8, 7, 1};
On diminue la taille du tableau de 1.
{10, 10, 11, 7, 98, 8, 7};
Notre élément est supprimé. :magicien:
/* Exercice 2 --------------------------------------------------------------- */
void afficherEltCommuns(int tableau1[], int tableau2[], int tailleTableau1,
                        int tailleTableau2)
{
    int i, j;
    for (i = 0; i < tailleTableau1; i++)
        for (j = 0; j < tailleTableau2; j++)
            if (tableau1[i] == tableau2[j])
            {
                /* Suppression de tableau2[j] */
                tableau2[j] = tableau2[tailleTableau2 - 1];
                tailleTableau2--;

                printf("%d ", tableau1[i]);
                break;
            }
    puts("");
}


Exercice 3


Les tris! :diable:
L'algorithme à utiliser était donné dans l'énoncé. On recherche le minimum ou le maximum du tableau et on le place à la bonne position.
On répète l'opération sur le reste du tableau.
Les 2 fonctions, avec en prime un fonction d'échange que vous avez déjà rencontré dans le cours.

/* Exercice 2 Tris ---------------------------------------------------------- */
void echange(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}



void triCroissant(int tableau[], int tailleTableau)
{
    int i;
    for (i = 0; i < tailleTableau ; i++)
    {
        int iMax = indexMax(tableau, tailleTableau - i);
        if(tailleTableau - i - 1 != iMax)
	    echange(&tableau[tailleTableau - i - 1], &tableau[iMax]);
    }
}

void triDecroissant(int tableau[], int tailleTableau)
{
    int i;
    for (i = 0; i < tailleTableau ; i++)
    {
        int iMin = indexMin(tableau, tailleTableau - i);
        if(tailleTableau - i - 1 != iMin)
            echange(&tableau[tailleTableau - i - 1], &tableau[iMin]);
    }
}


Exercice 4


void zeroADroite(int tableau[], int tailleTableau);


Ici, tout simplement, on peut lorsqu'on rencontre un zéro, le remplacer par l'élément à sa droite.
Seulement dans le cas d'un tableau comportant plusieurs éléments nul successifs c'est inadapté.
En effet, on se retrouve à échanger un zéro par ... un zéro!

Pour éviter ce problème, dès qu'on rencontre un élément nul, on va chercher le prochain élément non nul, et les échanger...
Un exemple avec ce tableau :

{1, 0, 4, 0, 0, -7}

On recherche le premier élément nul.
{1, 0, 4, 0, 0, -7}
On recherche le prochain élément non nul.
{1, 0, 4, 0, 0, -7}
On les échange
{1, 4, 0, 0, 0, -7}
On recherche le prochain élément nul.
{1, 4, 0, 0, 0, -7}
On recherche le prochain élément non nul.
{1, 4, 0, 0, 0, -7}
On les échange.
{1, 4, -7, 0, 0, 0}
On recherche le prochain élément nul.
{1, 4, -7, 0, 0, 0}
On recherche le prochain élément non nul.
Il n'y en à pas, on à teminé...

/* exercice 4 --------------------------------------------------------------- */
void zeroADroite(int tableau[], int tailleTableau)
{
    int i;
    for (i = 0; i < tailleTableau - 1; ++i)
        if (tableau[i] == 0)
        {
            int j;
            for(j = i + 1; j < tailleTableau && tableau[j] == 0; j++)
                ;

            if (j < tailleTableau)
            {
                tableau[i] = tableau[j];
                tableau[j] = 0;
            }
            else
                break;
        }
}


Toutes nos fonctions dans un petit programme de test.

</h4>
#include <stdio.h>

void affiche_tab(int *tableau, int tailleTableau)
{
    int *p_fin = tableau + tailleTableau;
    for (; tableau < p_fin; tableau++)
        printf("%d ", *tableau);
    puts("");
}



/* Exercice 1---------------------------------------------------------------- */
int indexMin(int tableau[], int tailleTableau)
{
    int i;
    int iMin = 0;

    for (i = 1; i < tailleTableau; i++)
        if (tableau[i] < tableau[iMin])
            iMin = i;

    return iMin;
}

int indexMax(int tableau[], int tailleTableau)
{
    int i;
    int iMax = 0;

    for (i = 1; i < tailleTableau; i++)
        if (tableau[i] > tableau[iMax])
            iMax = i;

    return iMax;
}



/* Exercice 2 --------------------------------------------------------------- */
void afficherEltCommuns(int tableau1[], int tableau2[], int tailleTableau1,
                        int tailleTableau2)
{
    int i, j;
    for (i = 0; i < tailleTableau1; i++)
        for (j = 0; j < tailleTableau2; j++)
            if (tableau1[i] == tableau2[j])
            {
                tableau2[j] = tableau2[tailleTableau2 - 1];
                tailleTableau2--;

                printf("%d ", tableau1[i]);
                break;
            }
    puts("");
}


/* Exercice 3 Tris ---------------------------------------------------------- */
void echange(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}


void triCroissant(int tableau[], int tailleTableau)
{
    int i;
    for (i = 0; i < tailleTableau ; i++)
    {
        int iMax = indexMax(tableau, tailleTableau - i);
        if (tailleTableau - i - 1 != iMax)
            echange(&tableau[tailleTableau - i - 1], &tableau[iMax]);
    }
}

void triDecroissant(int tableau[], int tailleTableau)
{
    int i;
    for (i = 0; i < tailleTableau ; i++)
    {
        int iMin = indexMin(tableau, tailleTableau - i);
        if (tailleTableau - i - 1 != iMin)
            echange(&tableau[tailleTableau - i - 1], &tableau[iMin]);
    }
}


/* exercice 4 --------------------------------------------------------------- */
void zeroADroite(int tableau[], int tailleTableau)
{
    int i;
    for (i = 0; i < tailleTableau - 1; ++i)
        if (tableau[i] == 0)
        {
            int j;
            for (j = i + 1; j < tailleTableau && tableau[j] == 0; j++)
                ;

            if (j < tailleTableau)
            {
                tableau[i] = tableau[j];
                tableau[j] = 0;
            }
            else
                break;
        }
}


/* -------------------------------------------------------------------------- */


#define NELEM(a)(sizeof (a) / sizeof (*a))

int main(void)
{
    int tab1[] = { 3, 4, 5, 1, 2 };
    int tab2[] = {0, 0, 1, 0, 4, 0, 0, -7 };
    int tab3[] = {0, 1, 10, 11, 10, 10};
    int tab4[] = {10, 1, 11, 7, 98, 8, 7, 10};

    printf("ind max: %d\n", indexMax(tab1, NELEM(tab1)));
    printf("ind min: %d\n", indexMin(tab1, NELEM(tab1)));
    printf("Elt com: ");
    afficherEltCommuns(tab3, tab4, NELEM(tab3), NELEM(tab4));

    printf("Tri cro: ");
    triCroissant(tab1, NELEM(tab1));
    affiche_tab(tab1, NELEM(tab1));

    printf("Tri dec: ");
    triDecroissant(tab1, NELEM(tab1));
    affiche_tab(tab1, NELEM(tab1));

    printf("Zer a d: ");
    zeroADroite(tab2, NELEM(tab2));
    affiche_tab(tab2, NELEM(tab2));

    return 0;
}


Et pour finir les mêmes en version pointeur :ninja:

#include <stdio.h>

void affiche_tab(int *tableau, int tailleTableau)
{
    int *p_fin = tableau + tailleTableau;
    for (; tableau < p_fin; tableau++)
        printf("%d ", *tableau);
    puts("");
}



/* Exercice 1---------------------------------------------------------------- */

/* En paramètre de fonction, int *tableau et int tableau[]sont équivalents.
 * Lors du passage à une fonction le tableau est convertit en pointeur vers
 * son premier élément.
 *
 * Plutôt que retourner l'index, on va retourner l'adresse du min et du max.
 * De même plutot que recevoir la taille du tableau, la fonction prend en
 * paramètre un pointeur sur la fin du tableau;
 *
 */
int *minPtr(int *tableau, int *fin)
{
    int *min = tableau;

    for (++tableau ;tableau < fin; tableau++)
        if (*tableau < *min)
            min = tableau;

    return min;
}


int *maxPtr(int *tableau, int *fin)
{
    int *max = tableau;

    for (++tableau ;tableau < fin; tableau++)
        if (*tableau > *max)
            max = tableau;

    return max;
}
/* Exercice 2 Tris ---------------------------------------------------------- */
void echange(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}


void triCroissantPtr(int *tableau, int tailleTableau)
{
    int *p_fin = tableau + tailleTableau;
    for (; tableau != p_fin ; p_fin--)
    {
        int *max = maxPtr(tableau, p_fin);
        if(max != p_fin - 1)
	    echange(p_fin - 1, max);
    }
}



void triDecroissantPtr(int *tableau, int tailleTableau)
{
    int *p_fin = tableau + tailleTableau;
    for (; tableau != p_fin ; p_fin--)
    {
        int *min = minPtr(tableau, p_fin);
        if(min != p_fin - 1)
            echange(p_fin - 1, min);
    }
}

/* Exercice 2 --------------------------------------------------------------- */
void afficherEltCommunsPtr(int tableau1[], int tableau2[], int tailleTableau1,
                           int tailleTableau2)
{
    int *p_tab1 = tableau1;

    int *p_fin1 = tableau1 + tailleTableau1 - 1;
    int *p_fin2 = tableau2 + tailleTableau2 - 1;

    for (; p_tab1 <  p_fin1; p_tab1++)
    {
        int *p_tab2 = tableau2;
        for (; p_tab2 < p_fin2; p_tab2++)
            if (*p_tab1 == *p_tab2)
            {
                *p_tab2 = *p_fin2;
                p_fin2--;

                printf("%d ", *p_tab1);

                break;
            }
    }
    puts("");
}



/* exercice 4 --------------------------------------------------------------- */
void zeroADroitePtr(int *tableau, int tailleTableau)
{
    int *p_tab = tableau;
    int *p_fin = tableau + tailleTableau;
    for (; p_tab < p_fin - 1; p_tab++)
        if (*p_tab == 0)
        {
            int *p_tmp = p_tab + 1;
            for (; p_tmp < p_fin && *p_tmp == 0; p_tmp++)
                ;

            if (p_tmp < p_fin)
            {
                *p_tab = *p_tmp;
                *p_tmp = 0;
            }
            else
                break;
        }
}

/* -------------------------------------------------------------------------- */
#define NELEM(a)(sizeof (a) / sizeof (*a))
int main(void)
{
    int tab1[] = { 3, 4, 5, 1, 2 };
    int tab2[] = {0, 0, 1, 0, 4, 0, 0, -7 };
    int tab3[] = {0, 1, 10, 11, 10, 10};
    int tab4[] = {10, 1, 11, 7, 98, 8, 7, 10};

    printf("ind max: %d\n", maxPtr(tab1, tab1 + NELEM(tab1)) - tab1);
    printf("ind min: %d\n", minPtr(tab1, tab1 + NELEM(tab1)) - tab1);
    printf("Elt com: ");
    afficherEltCommunsPtr(tab3, tab4, NELEM(tab3), NELEM(tab4));

    printf("Tri cro: ");
    triCroissantPtr(tab1, NELEM(tab1));
    affiche_tab(tab1, NELEM(tab1));

    printf("Tri dec: ");
    triDecroissantPtr(tab1, NELEM(tab1));
    affiche_tab(tab1, NELEM(tab1));

    printf("Zer a d: ");
    zeroADroitePtr(tab2, NELEM(tab2));
    affiche_tab(tab2, NELEM(tab2));

    return 0;
}


Exercice 5


Le triangle de Pascal.
Rappel:

Citation : Wikipédia


En écrivant la formule de Pascal,

pour tous entiers i et j tels que 0 < j < i, <math>\({i \choose j}={i-1 \choose j-1}+{i-1 \choose j}\)</math>

nous remarquons que le coefficient de la ligne i et colonne j s'obtient en ajoutant les coefficients de la ligne i - 1 et colonne j - 1 et de la ligne i - 1 et colonne j. De plus nous savons que

<math>\({n \choose 0}={n \choose n}=1.\)</math>
Nous en déduisons une méthode de construction du triangle de Pascal :

* nous plaçons dans la colonne 0 des 1 à chaque ligne, et des 1 à chaque entrée de la diagonale,
* en partant du haut et en descendant, nous complétons le triangle en ajoutant deux coefficients adjacents d'une ligne, pour produire le coefficient de la ligne inférieure, en dessous du coefficient de droite.




Pour constuire la ligne n, du triangle de Pascal, on a uniquement besoin de la ligne n - 1.
Aussi, nous allons utiliser 2 tableaux.
  • Un pour la ligne précédente
  • Un pour la ligne courante

Une fois la ligne courante construite, il suffit d'échanger les 2 tableaux et notre ligne courante devient notre ligne précédente...
Pour échanger les tableaux, on échangera uniquement les pointeurs sur le premier élément de chaque tableau.

#include <stdio.h>

#define SIZE 10

void swap(int **pp_a1, int **pp_a2)
{
    int *p_tmp = *pp_a1;
    *pp_a1 = *pp_a2;
    *pp_a2 = p_tmp;
}



void afficherLigne(int *crt, int n)
{
    int i;

    for(i = 0; i <= n; ++i)
        printf("%4d ", crt[i]);
    putchar('\n');
}

int main(void)
{

	int prv[SIZE] = {1};
	int crt[SIZE];
	int *p_prv = prv;
	int *p_crt = crt;

	int lin, col;

    for (lin = 0; lin < SIZE; ++lin)
    {
        crt[lin] = 1;
        crt[0] = 1;
        for (col = 1; col <= lin; ++col)
            p_crt[col] = p_prv[col] + p_prv[col - 1];

        afficherLigne(crt, lin);

        swap(&p_prv, &p_crt);
    }

    return 0;
}


Si on est malin, on peu se rendre compte, qu'il suffit d'un seul tableau pour construire le triangle.
Pensez à construire la ligne courante par la droite.


Exercice 6



La fonction
int kEmeElt(int tableau[], int tailleTableau, int k);


En première approche, une première méthode est de trier le tableau et de retourner l'élément à l'emplacement k.
/* Kème plus petit élément d'un tableau ------------------------------------- */
int kEmeElt(int tableau[], int tailleTableau, int k)
{
    triCroissant(tableau, tailleTableau);

    return tableau[k];
}

Evidement, la fonction de tri utilisée est primordiale. Notre fonction de tri à une complexité dans le pire des cas en O(<math>\(N^2\)</math>).
La notion de complexité
Pour des tableaux de tailles plus importantes, il faudra utiliser une fonction de tri plus efficace comme qsort de la libc, ou se pencher vers d'autre algorithmes ou d'autres structures de données.

Concernant les structures de données, vous pouvez regarder du coté du tas.

Pour des algorithmes plus performants, vous pouvez regarder Selection algorithm ainsi que les codes de Pouet_forever, mob.

Exercice 7



int mode(int tableau[], int tailleTableau]);


Pour cet exercice la solution à adopter est fonction des données traitées.
Si la plage de valeur est petite(par exemple l'alphabet), la meilleure solution est de d'utiliser un tableau de [VALEUR_MIN à VALEUR_MAX], et incrémenter la case tab[VALEUR] pour chaque occurrence de VALEUR. En conservant la trace du mode actuel, il suffit d'une passe du tableau pour résoudre le problème... voir ici.

Si la plage de valeur devient très grande, alors cette solution n'est pas utilisable(trop de mémoire utilisée)...

On peut commencer par une solution naïve, une double boucle mais ne pas traiter une même valeur plusieurs fois. Pour cela, à chaque valeur rencontré, on parcourt le tableau à la recherche de cette valeur et on la supprime
int mode1(int tableau[], int tailleTableau)
{
    int i, j;
    int maxVal = tableau[0];
    int maxOcc = 1;

    for (i = 1; i < tailleTableau; ++i)
    {
        int occ = 1;
        for (j = i + 1; j < tailleTableau; ++j)
            while (tableau[j] == tableau[i])
            {
                occ++;
                echange(&tableau[j], &tableau[--tailleTableau]);
            }
        if (occ > maxOcc)
        {
            maxOcc++;
            maxVal = tableau[i];
        }

    }
    return maxVal;
}


Une autre solution(meilleure) est de trier(avec un tri efficace) le tableau et d' effectuer une parcours linéaire.

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


static int cmp(const void *pa, const void *pb)
{
    const int a = *(const int *)pa;
    const int b = *(const int *)pb;

    if (a < b)
        return -1;
    else if (a > b)
        return 1;
    else
        return 0;
}



int modeQsort(int tableau[], int tailleTableau)
{
    int i;
    int maxVal, maxOcc;

    qsort(tableau, tailleTableau ,sizeof *tableau, cmp);

    maxVal = tableau[0];
    maxOcc = 1;

    for (i = 1; i < tailleTableau; i++)
        if (tableau[i] == tableau[i - maxOcc])
    {
        maxOcc++;
        maxVal = tableau[i];
        }
    return maxVal;
}


Pour faire mieux, cela devient beaucoup plus compliqué, et il faut utiliser une autre structure de donnée, comme une table de hashage..
Un exemple avec La solution proposée par Arthurus.

La solution qsort est beaucoup plus simple, et reste très efficace...


Merci encore aux participants.
Pour le prochain exercice, on s'attaquera aux opérations sur les grands entiers. GMP peut trembler(ou pas)! :pirate:
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
13 février 2010 à 20:08:52

Une correction d'une qualité toujours aussi exceptionnelle.
Félicitations.
  • Partager sur Facebook
  • Partager sur Twitter
13 février 2010 à 20:13:29

+1 Lithrein
Belle correction

les deux premiers codes, c'est la même fonction, tu as mis Min au lieu de Max à une des deux. :D
  • 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)
13 février 2010 à 21:47:10

Cool tout ça :)
J'attend la suite avec impatience :D
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 4:48:04

Merci beaucoup! :) Je vous assure que cela me fais réellement plaisir(et j'ai toujours peur de me planter. :-° )

@schadocalex:
Je ne comprend pas. Effectivement, les deux premières fonctions sont presques identiques sauf(<, >)... Que veux tu dire, stp? S'il y a une erreur, merci de me la préciser pour que je corrige au plus vite.

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

exercice 1 :
IndexMin(...)
IndexMin(...)

Juste une erreur de frappe je pense. Enfin, relis tes deux premières balises code ;)
Sinon, c'est pas mal ..
  • 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)
14 février 2010 à 10:02:07

Citation : GurneyH

exercice 1:


Les fonctions

int indexMin(int tableau[], int tailleTableau);

et

int indexMin(int tableau[], int tailleTableau);

^^
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 12:23:08

J'espère bien un jour un exo sur SDL !
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 12:36:15

@Arthurus : Shareman a précisé dans son premier post que ce serait des exos n'ayant besoin que de la lib standart, je sais pas si GurneyH va continuer ^^ .

@GurneyH : Encore du très beau boulot, la correction est très détaillée.
Par contre la formule de Pascal o_O , je comprends rien.

Vivement le prochain exo ! :D .
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 13:45:13

Citation : Colb-Seton

Par contre la formule de Pascal o_O , je comprends rien.

Tu n'as pas vu les vecteurs en maths ?
  • 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)
14 février 2010 à 14:01:49

Citation : schadocalex

Tu n'as pas vu les vecteurs en maths ?


Si.
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 14:07:22

Bah là on peut plus rien pour toi :lol:
Reprend tes cours :p
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 14:35:06

Titre : zBigInt
Mois : Second exercice de février 2010
Sujet : Opérations surs les grands entiers.
Connaissances requises : Partie 2 : [Théorie] Techniques avancées

Objectif


Soit a et b 2 nombres entiers positifs en base 10, représentés sous forme de chaînes de caractères.

exercice 1



Ecrire la fonction
void addition(char *a, char *b, char *c);

A la sortie de la fonction, la chaîne c, contiendra le résultat de l'addition de a et b.

Connaissant le nombre de chiffres de a et de b, réfléchissez au nombre maximum de chiffres possible pour c, et déclarez c avec une taille suffisante.

Exemple
void addition(char *a, char *b, char *c);

int main (void)
{
    char a[11] = "1234567890";
    char b[11] = "332";
    char c[?] = "";

    addition(a, b, c);

    printf("%s\n", c);

    return 0;

}

1234568222


Pour réaliser l'addition, la méthode est la même que celle apprise en école primaire.

Ecrire la fonction
void soustraction(char *a, char *b, char *c);

A la sortie de la fonction, la chaîne c contiendra le résultat de la soustraction de a et b. Si le résultat de la soustraction est négatif, la chaîne c devra débuter par le signe '-'.

Encore une fois, la méthode à employer est la même que celle apprise à l'école primaire.
Réféchissez à la manière de traiter le cas ou a < b.

Enfin, écrire la fonction
void multiplication(char *a, char *b, char *c);

Pour commencer, demandez vous quel est le nombre de chiffres maimum de c, connaissant le nombre de chiffres de a et b.

Exercice 2



Même exercice que le 1, mais ici a et b
  • Pourront être négatifs
  • Pourront être exprimés dans une base quelconque entre 2 et 16.

Avec "0123456789abcdef"

a, b et c seront exprimés dans la même base.

Petit rappel sur l'écriture des nombres.
En base 10, le nombre abcd est égal à <math>\(a * 10^3 + b * 10^2 + c * 10^1 + d * 10 ^0\)</math>

Dans une base B quelconque, abcde est égal à <math>\(a * B^3 + b * B^2 + c * B^1 + d * B ^0\)</math>



Le prototype des fonctions devient
void addition(char *a, char *b, char *c, int base);
void soustraction(char *a, char *b, char *c, int base);
void multiplication(char *a, char *b, char *c, int base);


Exemple :
int main(void)
{
    char a[100] = "a";
    char b[100] = "6";
    char c[100] = "";

    additionBase(a, b, c, 16);

    printf("%s\n", c);

    return 0;
}

10



Un topic est ouvert ici pour poster vos solutions.

edit:
La partie avancée a été supprimée, car probablement trop compliquée, et les 2 premiers exercices offrent déjà pas mal de difficultés pour une durée de 15 jours.
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
14 février 2010 à 14:39:31

haha, monsieur fait de l'orienté objet ;)
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 14:43:52

Citation : Arthurus


haha, monsieur fait de l'orienté objet ;)


J'ai surtout copié l'interface de GMP. ;)
  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
14 février 2010 à 15:00:03

Est ce que a et b ont forcément la même taille ?
On doit faire comme ça :
char *a = "1000", *b = "0050";

// ou 

char *a = "1000", *b = "50";
?
Merci,
  • Partager sur Facebook
  • Partager sur Twitter
14 février 2010 à 15:04:33

Non, a et b n'ont pas forcément la même taille. je modifie mon exemple. ;)


  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
14 février 2010 à 15:06:12

Intéréssant, je le ferais surement. Mais comment savoir à l'avance le nombre de dizaine de c ? On peut, ou on ne peut pas et c'est au fur et à mesure de l'addition ?
  • 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)