begin process at 2012 05 27 18:37:45
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > MELANGER N'IMPORTE QUOI

MELANGER N'IMPORTE QUOI


 Information sur la source

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :10/12/2003 Date de mise à jour :11/12/2003 08:25:02 Vu :5 323

Auteur : garslouche

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

 Description

Le principe est simple : vous avez un tableau de n'importe quoi (chaine de caractères, classe quelconque, ...) et vous voulez mélanger ces éléments.

Fastoche!

C'et un petit prog en C qui mélange en fait un liste d'index (allant de 0 à N-1).
Il suffit alors d'utiliser les index mélangés pour mélanger votre liste. Vous me suivez ?

Bon un exemple ... un jeu de 32 cartes

Source

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <time.h>
  • inline void melange(int* tableau, int nTaille)
  • {
  • int i;
  • for (i = 0; i<nTaille; i++)
  • tableau[i] = -1;
  • for (i = 0; i<nTaille; i++)
  • {
  • int nPos = rand() % nTaille;
  • while (tableau[nPos%nTaille] != -1)
  • nPos++;
  • tableau[nPos%nTaille] = i;
  • }
  • }
  • #define TAILLE 32
  • int main(int argc, char* argv[])
  • {
  • srand( (unsigned)time( NULL ) );
  • int nIndex[TAILLE];
  • melange(nIndex, TAILLE);
  • char* cartes[TAILLE] = {
  • "Sept de pique",
  • "Sept de coeur",
  • "Sept de carreau",
  • "Sept de trefle",
  • "Huit de pique",
  • "Huit de coeur",
  • "Huit de carreau",
  • "Huit de trefle",
  • "Neuf de pique",
  • "Neuf de coeur",
  • "Neuf de carreau",
  • "Neuf de trefle",
  • "Dix de pique",
  • "Dix de coeur",
  • "Dix de carreau",
  • "Dix de trefle",
  • "Valet de pique",
  • "Valet de coeur",
  • "Valet de carreau",
  • "Valet de trefle",
  • "Dame de pique",
  • "Dame de coeur",
  • "Dame de carreau",
  • "Dame de trefle",
  • "Roi de pique",
  • "Roi de coeur",
  • "Roi de carreau",
  • "Roi de trefle",
  • "As de pique",
  • "As de coeur",
  • "As de carreau",
  • "As de trefle"
  • };
  • for (int i=0; i<TAILLE; i++)
  • printf("%s\n", cartes[nIndex[i]]);
  • system("pause");
  • return 0;
  • }
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

inline void melange(int* tableau, int nTaille)
{
	int i;

	for (i = 0; i<nTaille; i++)
		tableau[i] = -1;

	for (i = 0; i<nTaille; i++)
	{
		int nPos = rand() % nTaille;

		while (tableau[nPos%nTaille] != -1)
			nPos++;

		tableau[nPos%nTaille] = i;
	}

}

#define TAILLE 32
int main(int argc, char* argv[])
{
	srand( (unsigned)time( NULL ) );

	int nIndex[TAILLE];
	melange(nIndex, TAILLE);

	char* cartes[TAILLE] = {
		"Sept de pique",
		"Sept de coeur",
		"Sept de carreau",
		"Sept de trefle",

		"Huit de pique",
		"Huit de coeur",
		"Huit de carreau",
		"Huit de trefle",

		"Neuf de pique",
		"Neuf de coeur",
		"Neuf de carreau",
		"Neuf de trefle",

		"Dix de pique",
		"Dix de coeur",
		"Dix de carreau",
		"Dix de trefle",

		"Valet de pique",
		"Valet de coeur",
		"Valet de carreau",
		"Valet de trefle",

		"Dame de pique",
		"Dame de coeur",
		"Dame de carreau",
		"Dame de trefle",

		"Roi de pique",
		"Roi de coeur",
		"Roi de carreau",
		"Roi de trefle",

		"As de pique",
		"As de coeur",
		"As de carreau",
		"As de trefle"
	};

	for (int i=0; i<TAILLE; i++)
		printf("%s\n", cartes[nIndex[i]]);

	system("pause");

	return 0;
}

 Conclusion

Ce code est pour VC++ mais il devrait fonctionner avec n'importe quel compilo.

La ligne system("pause") peut poser problème avec certains compilo....enlevez là !

############################################### #####

Bon maintenant des explications sur l'algo :

Souvent je trouve des mélanges de type "swap". C'est-à-dire qu'on echange deux elements pris au hasard, et on recommence un grand nombre de fois. Le problèmes de ces mélange c'est que un "grand" nombre de fois ne veut pas dire grand chose et qu'en plus ça implique un temps de calcul lui aussi "grand".
Donc cette méthode ne me plait pas trop.

Il y a un autre type de mélange qui consiste à prendre un par un tous les index. Pour chaque index on choisit une place au hasard, et si cette place est deja prise on en cherche une autre au hasard jusqu'à tomber sur une case vide. Le problème de cet algo c'est que les derniers index vont avoir du mal à trouver une place. Puisque par exemple pour le jeu de cartes, la derniere carte n'a qu'une place dispo parmi 32 et celle d'avant n'avait que 2 places sur 32... Donc beaucoup d'itérations en perspective !

Ma méthode est simple : on prend les index un par un et on essaie de les placer au hasard dans une liste d'index. Si la place est libre tant mieux : on la prend, sinon on essaie la case juste après jusqu'à tomber sur une case vide.


 Sources du même auteur

Source avec Zip CLABEL : UN CSTATIC AMÉLIORÉ
Source avec Zip [WIN32] LANGAGE DE SCRIPT POUR AUTOMATISER DES ACTIONS DANS ...
PROPRIÉTÉS D'UN FICHIER / D'UN DOSSIER FAÇON WINDOWS
Source avec Zip LES FONCTIONS DE MATH.H REPROGRAMMÉES
Source avec Zip Source avec une capture CALENDRIER INCRUSTÉ SUR LE BUREAU [WIN32]

 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 hoiby le 10/12/2003 19:14:34

Salut, moi j'ai trouvé une autre solution (je pense qu'elle est plus perfomante en terme de vitesse, mais j'en suis pas sûr).

#include &lt;stdlib.h&gt;

int compare( const void* arg1, const void* arg2 ){ return (rand()+1)&lt;&lt;31; }

int main(int argc, char* argv[]){

  int nIndex[]={0,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};

  qsort(nIndex,sizeof(nIndex)/sizeof(*nIndex),sizeof(*nIndex),compare);
  return 0;
}


Commentaire de garslouche le 10/12/2003 19:39:33

Merci de cet algo pluot original je dois l'avouer!
Par contre comme je le pensais ta méthode est plus longue. Pour la bonne et simple raison que le tri rapide n'est pas si rapide que ça...Il est en O(n.log n) en moyenne, ce qui est le mieux pour un tri. Mais au pire des cas il atteint O(n^2). Bref, tout ça pour dire que le tri reste un algo relativement lourd.

Apres des tests sur 100 000 mélanges, ma méthode se révèle être 2.5 fois plus rapide.

Mais je ne connaissais pas la fonction qsort...merci !

Commentaire de garslouche le 11/12/2003 08:25:20

Ah ... en fait c'est plus vicieux que je croyais...
D'abord j'avais fait ce test en debug en pas en release. Et en release on arrivait à une vitesse équivalente.
Par contre j'ai oublié de mettre un truc très important pour optimiser mon algo : le mot clé 'inline' (que j'ai ajouté dans la mise à jour de la source). Pour ceux qui ne connaissent pas, ça demande au compilateur de copier le contenu de la fonction à chaque appel de celle-ci. Du coup c'est plus rapide mais les EXE sont plus gros.

Et là mon algo devient environ 7 fois plus rapide en release (sur 1 million de melanges). Par contre en debug ça tourne tojours à 2.5.

Pour info voici comment j'ai fait le test :

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

#include &lt;sys/types.h&gt;
#include &lt;sys/timeb.h&gt;

int compare( const void* arg1, const void* arg2 ){ return (rand()+1)&lt;&lt;31; }

inline void melange(int* tableau, int nTaille)
{
int i;

for (i = 0; i&lt;nTaille; i++)
tableau[i] = -1;

for (i = 0; i&lt;nTaille; i++)
{
int nPos = rand() % nTaille;

while (tableau[nPos%nTaille] != -1)
nPos++;

tableau[nPos%nTaille] = i;
}

}

#define TAILLE 32
#define MELANGES 1000000

int main(int argc, char* argv[])
{
srand( (unsigned)time( NULL ) );

_timeb t0, t1, t2;

_ftime(&t0);

// Premiere méthode
{
int nIndex[TAILLE];
for (int i = 0; i&lt;MELANGES; i++)
melange(nIndex, TAILLE);
}

_ftime(&t1);

// Deuxieme méthode
{
int nIndex[]={0,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};
for (int i = 0; i&lt;MELANGES; i++)
qsort(nIndex,sizeof(nIndex)/sizeof(*nIndex),sizeof(*nIndex),compare);
}

_ftime(&t2);


// Calcul des durées
int test1 = (t1.time-t0.time)*1000 + (t1.millitm-t0.millitm);
int test2 = (t2.time-t1.time)*1000 + (t2.millitm-t1.millitm);

printf("##### 1 000 000 itérations #####
Premiere méthode : %d ms
Seconde méthode  : %d ms
Le premier test est %f fois plus rapide
", test1, test2, test2/(float)test1);

system("pause");

return 0;
}

Commentaire de hoiby le 11/12/2003 12:09:51

Tu as raison mon algo est vraiment nul. (en terme de vitesse)
Mais bon j'ai trouvé ça sympa d'utiliser qsort pour mélanger :)

 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,484 sec (3)

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