begin process at 2012 05 27 17:55:24
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > PROGRAMME DE TRI

PROGRAMME DE TRI


 Information sur la source

Note :
Aucune note
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :14/07/2004 Date de mise à jour :14/07/2004 18:04:10 Vu / téléchargé :7 493 / 141

Auteur : ekinoks

Ecrire un message privé
Site perso
Commentaire sur cette source (19)
Ajouter un commentaire et/ou une note

 Description

Voici mon 1ere programme en C.
J'ai realisé un programme de tri de nombres, j'ai reflechie plusieur jour a un bon algorithm pour que le programme classe le plus de nombres le plus rapidement possible. Le programme classe actuelement sur mon pc 1.000.000 chiffres allent de 0 a 1.000.000 en 63Ms.

Source

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <windows.h>
  • int main(int argc, char *argv[])
  • {
  • DWORD deb, fin;
  • int tmp,a,b,c,d,e;
  • printf("nombres de chiffres a classer ?");
  • scanf("%i", &c);
  • printf("nombres allent de 0 a ?");
  • scanf("%i", &d);
  • printf("Voullez vous affichier les chiffre une foi classer ? (oui = 1; non = 0)");
  • scanf("%i", &e);
  • int tab [2][d];
  • int tab2 [c];
  • for (a=0;a<c;a++) // Inscrit des nobres aleatoirement //
  • tab2[a]=(rand()%d); // dans le tableau tab2 //
  • deb = GetTickCount(); // debut du crono //
  • for (a=0;a<c;a++) // fait autent de boucle qu'il y a de nombre a classer //
  • {
  • tmp=tab2[a];
  • if (tab[0][tmp] == tmp) // si le nombre a deja été classer, alors rejouté + 1 //
  • tab[1][tmp] = tab[1][tmp] + 1; // a la desieme ligne de la colone tmp //
  • else
  • {
  • tab[1][tmp] = 0; // si le chiffre n'a jamais été classer, inisialiser la desieme ligne de la colone tmp a 0 //
  • tab[0][tmp] = tmp;
  • }
  • }
  • if (e == 0) // si il ne fo pas affichier les chiffre //
  • {
  • //printf("chiffre classer du plus petit au plus grand : \n");
  • for (a=1;a<d;a++) // lire tout les casse de la 1ere ligne du tableau //
  • {
  • if (tab[0][a] == a) // si le N° de la case est le meme que le que le N° qu'il y a dedans //
  • {
  • //printf("%i\n", tab[0][a]);
  • for (b=0;b<tab[1][a];b++) // boucle pour afficher plusieur foi les chiffre ki on apparu plusieur foi //
  • {
  • // printf("%i\n", tab[0][a]);
  • }
  • }
  • }
  • }
  • if (e == 1) // si il fo affichier les chiffre //
  • {
  • printf("chiffre classer du plus petit au plus grand : \n");
  • for (a=1;a<d;a++) // lire tout les casse de la 1ere ligne du tableau //
  • {
  • if (tab[0][a] == a) // si le N° de la case est le meme que le que le N° qu'il y a dedans //
  • {
  • printf("%i\n", tab[0][a]);
  • for (b=0;b<tab[1][a];b++) // boucle pour afficher plusieur foi les chiffre ki on apparu plusieur foi //
  • {
  • printf("%i\n", tab[0][a]);
  • }
  • }
  • }
  • }
  • fin = GetTickCount(); //fin du crono
  • printf("le tri a mi %d Ms", fin - deb);
  • while(1==1);
  • //Pause infini pour eviter que le programme se ferme une foi le trie terminé
  • return 0;
  • }
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main(int argc, char *argv[])
{
  DWORD deb, fin;
  int tmp,a,b,c,d,e;
  printf("nombres de chiffres a classer ?");
  scanf("%i", &c);
  printf("nombres allent de 0 a ?");
  scanf("%i", &d);
  printf("Voullez vous affichier les chiffre une foi classer ? (oui = 1; non = 0)");
  scanf("%i", &e);
  int tab [2][d];
  int tab2 [c];

  for (a=0;a<c;a++)        //   Inscrit des nobres aleatoirement   //
  tab2[a]=(rand()%d);      //         dans le tableau tab2         //

  deb = GetTickCount();      //   debut du crono   //

  for (a=0;a<c;a++)          //   fait autent de boucle qu'il y a de nombre a classer   //
  {
   tmp=tab2[a];
   if (tab[0][tmp] == tmp)             //   si le nombre a deja été classer, alors rejouté + 1   //
   tab[1][tmp] = tab[1][tmp] + 1;      //          a la desieme ligne de la colone tmp           //
   else
   {
    tab[1][tmp] = 0;                  //   si le chiffre n'a jamais été classer, inisialiser la desieme ligne de la colone tmp a 0   //
    tab[0][tmp] = tmp;
   }
  }

  if (e == 0)         //   si il ne fo pas affichier les chiffre   //
  {
   //printf("chiffre classer du plus petit au plus grand : \n");
   for (a=1;a<d;a++)              //   lire tout les casse de la 1ere ligne du tableau   //
   {
    if (tab[0][a] == a)           //   si le N° de la case est le meme que le que le N° qu'il y a dedans   //
    {
     //printf("%i\n", tab[0][a]);
     for (b=0;b<tab[1][a];b++)      //   boucle pour afficher plusieur foi les chiffre ki on apparu plusieur foi   //
     {
      //  printf("%i\n", tab[0][a]);
     }
    }
   }
  }


  if (e == 1)            //   si il fo affichier les chiffre   //
  {
   printf("chiffre classer du plus petit au plus grand : \n");
   for (a=1;a<d;a++)               //   lire tout les casse de la 1ere ligne du tableau   //
   {
    if (tab[0][a] == a)            //   si le N° de la case est le meme que le que le N° qu'il y a dedans   //
    {
     printf("%i\n", tab[0][a]);
     for (b=0;b<tab[1][a];b++)    //   boucle pour afficher plusieur foi les chiffre ki on apparu plusieur foi   //
     {
      printf("%i\n", tab[0][a]);
     }
    }
   }
  }

  fin = GetTickCount();                    //fin du crono
  printf("le tri a mi %d Ms", fin - deb);

  while(1==1);
  //Pause infini pour eviter que le programme se ferme une foi le trie terminé

  return 0;
}

 Conclusion

N'esité pas a reagir si vous avez une idéé pour ameliorer la rapidité du tri.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  • Tri.cppTélécharger ce fichier [Réservé aux membres club]Voir ce fichier2 503 octets
  • Tri.exeTélécharger ce fichier [Réservé aux membres club]4 608 octets

Télécharger le zip


 Historique

14 juillet 2004 18:04:10 :
 

 Sources du même auteur

Source avec Zip PARTAGER SA CONNEXION INTERNET
Source avec Zip SCANNER D'IP
Source avec Zip PETITE CONSOL

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

Commentaires et avis

Commentaire de BlackGoddess le 14/07/2004 18:49:29

int tab [2][d]; >> tu compiles avec quel compilateur ?

normalement la taille d'un tableau DOIT être résolue a la compilation, hors la il est impossible de la connaître, puisque d est une saisie utilisateur (a l'execution donc).

Commentaire de djl le 14/07/2004 18:58:28

en c ca gueule avec -ansi -pedantic pour etre sur que c'est ansi, avant const ca n'existait meme pas

Commentaire de BruNews le 14/07/2004 19:02:13 administrateur CS

Comme on te l'a fait remarquer plus haut, ton code ne compiler jamais. Faut une alloc dynamique.
Rectif attendue, merci.

BruNews, Admin CS, MVP Visual C++

Commentaire de djl le 14/07/2004 19:02:17

ekinoks > tu devrai isoler ta methode de tri dans une fonction, ca sera plus facile de comparer (et plus reutilisable)

int *isort(int *tab,size_t size);

Commentaire de Cyberboy2054 le 14/07/2004 21:54:42

C' est plutôt bon comme resultat. Mon implementation de quicksort, bien qu' étant simpliste et recursive, met 10 fois plus de temps dans les memes conditions.
Est il possible de dérécursifier quicksort, ou y-a-t' il des moyens de l'optimiser (genre une methode rapide pour trouver un bon pivot) ?

Commentaire de BruNews le 14/07/2004 22:10:54 administrateur CS

C'est sur qu'un quicksort ne doit jamais etre recursif sinon il ne restera que le 'sort' mais ne sera plus 'quick' du tout. Toute fonction recursive est plus lente que la version iterative pour cause d'empilage des params a chaque tour.

Commentaire de Maegis le 14/07/2004 23:27:52

>>>Cyberboy  
Il ne faut pas faire la comparaison avec un quicksort, ici tu as plein d'indications supplementaires dont le fait que les nombres sont tous positifs et plus petits que d
La donnée de d permet d'optimiser la fonction de tri
Les algos de quicksort, de heapsort ou de tri fusion sont optimum pour la seule donnée de la taille du tableau et le tableau lui-même. Avec des indications supplementaires on peut faire beaucoup mieux et on peut avoir des tris linéaires (en O(n)) plutôt que des quasi-linéaires (en O(n*ln(n)) )

>>>>>ekinoks
Ta fonction ne trie pas le tableau, si on décide de ne pas afficher les valeurs ton prog ne fait aucune opération sur tab2
Si on affiche les results, tu les affiches et c'est tout, à la fin le tableau tab 2 n'est pas trié

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

int main(int argc, char *argv[])
{
    DWORD deb, fin;
    int i,j,k;
int* tmp;
int nbchiffres;
int max;
int *tab,*tab2;
    printf("Nombre de chiffres a classer ?");
    scanf("%i", &nbchiffres);
    printf("Nombres allant de 0 a ?");
    scanf("%i", &max);

//alloc
tab = new int[nbchiffres];
tab2 = new int[max];

    for (i=0;i<nbchiffres;i++)       //Inscrit des nombres aleatoirement
tab[i]=(rand()%max);

   ZeroMemory(tab2,max); //on init tout a zero

deb = GetTickCount();
for (i=0;i<nbchiffres;i++)
tab2[tab[i]]++; //on compte le nb de fois que chaque nombre apparait

tmp = tab; //on sauve le pointeur
for (i=0;i<max;i++) //on recompose le tableau
{
k = tab2[i];
for (j=0;j<k;j++)
{
*tab=i;
tab++;
}
}
tab = tmp; //on restaure

    fin = GetTickCount();                   //fin du crono
    printf("Le tri a mis %d Ms\n", fin - deb);

delete[] tab;
delete[] tab2;
system("pause");

    return 0;
}
voila cette fonction trie un tab de 1.000.000 , 1.000.000 en 30ms chez moi et le qsort de la stdlib met 60ms


>>>>>BruNews
Le quicksort est forcement recursif !!!!
Il applique la méthode diviser pour regner :
On coupe le tableau en 2 selon le pivot (1ere moitié contenant les cases plus petites que le pivot, 2eme moitié le reste) et on appelle recursivement le programme sur les deux morceaux de tableau ainsi obtenus
C'est du recursif pur, qui dit diviser pour regner dit recursif.
Quoi qu'il en soit le quicksort est un bon algo dans la moyenne ( O(N*ln(N) ) bien que dans le pire des cas on atteigne une complexité en O(N^2)
Sinon il y a toujours le tri par tas (heapsort) qui est toujours en O (N*ln(N))

Commentaire de BruNews le 14/07/2004 23:37:44 administrateur CS

pas du tout, tu trouves exemple dans le qsort de la crt, on simule le recursif par une remontee dans le code grace a une stack implementee en local.

Commentaire de BruNews le 14/07/2004 23:41:53 administrateur CS

Robert Sedgewick explique la suppression de la recursivite (comme dit plus haut) a partir de la page 128 de: "Algorithmes en langage C".

Commentaire de djl le 15/07/2004 00:02:29

comme  ca c'est efficace aussi ?

void swap_i(int *i1, int *i2)
{
    int i = *i1;
    
    *i1 = *i2;
    *i2 = i;
}

size_t min_i(int *v, size_t size)
{
    int min = *v, *p = v;
    size_t i = 0, ind_min = 0;
        
    while( ++i < size )
        if( *(++p) < min )
        {
            min = *p;
            ind_min = i;
        }
        
    return ind_min;
}

void sort_i(int *v, size_t size)
{
    size_t i;
    int *p = v;
    
    for( i = 0; i < size; i++, p++)
        swap_i( p, p + min_i(p, size - i) );
}


par exemple

int v[]={1,3,6,5,9,2,7,45,45564,545,54,1,5,26,54,74,5215,54};
    
sort_i(v, sizeof v / sizeof *v );

Commentaire de djl le 15/07/2004 00:03:25

j'ai repris le meme algo de la methode sort() de ma classe matrice

Commentaire de BruNews le 15/07/2004 00:12:10 administrateur CS

djl > essaie de tout mettre dans la meme fonction pour qu'il n'y ait pas d'appels et d'empilage de params.

Commentaire de BruNews le 15/07/2004 00:15:44 administrateur CS

http://www.cppfrance.com/code.aspx?ID=11151
c'est exemple ou j'ai devie le qsort de la CRT pour tout faire en interne. Juste que la il trie plus qu'un simple tableau de int, on peut donc beaucoup reduire le code de tri.

Commentaire de djl le 15/07/2004 00:17:26

oui, mais en fait j'ai laissé comme ca car on a toujoursl a possibilité de specifier les fonctions swap_i et min_i inline (en c99) ce qui reviendrai au meme
la j'ai tenu à faire un code c ansi et clair, mais c'est sur que pour la performance il vaut mieux derouler le code ou specifier les fonctions inline

Commentaire de BruNews le 15/07/2004 00:25:42 administrateur CS

on est bien d'accord !!!

Commentaire de Maegis le 15/07/2004 12:22:40

Conclusion : ne pas croire les profs d'option info
On m'avait affirmé qu'on ne pouvait pas """"supprimer la recursivité"""" dans le qsort sans deteriorer les performances

Commentaire de BruNews le 15/07/2004 12:35:56 administrateur CS

Je n'irais pas jusque la (encore que...) mais faut surtout plusieurs sources d'informations. Je te conseille Robert Sedgewick qui est une reference absolue.

Commentaire de Maegis le 15/07/2004 13:07:22

Je parle bien d'option info, c'est a dire un petit programme, peu d'heures de cours et des profs qui ne connaissent que le programme et pas grand chose à coté.
Et si tu regardes les commentaires des codes sources tu remarquera qu'il y en a quelques uns du genre : "ah oui je savais pas, mon prof d'info m'a dit le contraire"

Et merci pour l'info, je vais de ce pas acheter 1 bon livre d'algorithmique, je vais voir si je trouve un de ses bouquins

Commentaire de StanOfSky le 15/07/2004 23:54:35

ba de toute maniere ca existe po la récursivité en info d'un point de vu purement physique... c juste une écriture plus lisible et plus facile à démontrer d'un point de vu mathématique.
en fait au résultat c du linéaire : t'empiles, tu dépiles...
apres tu peu avoir des compilo qui optimisent à fond et optenir le meme résultat en ayant ecrire une fonction récursive qu'en l'ayant déroulé et fait tout meme le systeme de pile.
seul l'assembleur reste la meilleur solution pour etre certain d'avoir une fonctions optimisée a fond ;)

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,452 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales