Bonjour, j'aimerais, si c'est possible, savoir si ce code est optimisable s'il vous plait.
// Tant qu'on trouve un double on relance le tirage.
while ( $num1 == $num2 OR $num1 == $num3 OR $num1 == $num4 OR $num1 == $num5 OR $num2 == $num3 OR $num2 == $num4 OR $num2 == $num5 OR $num3 == $num4 OR $num3 == $num5 OR $num4 == $num5 )
{
$num1 = rand(1,50);
$num2 = rand(1,50);
$num3 = rand(1,50);
$num4 = rand(1,50);
$num5 = rand(1,50);
}
La partie pour laquelle je me pose la question est bien sûr la longue suite de variables que je compare une à une pour vérifier qu'il n'y a pas de doublon.
Par curiosité je me demande si on peut écrire ça autrement, de façon plus courte et aussi simple.
Merci d'avance.
Un truc du genre, de tête :
$nums = array();
$keyIndex = array();
while( count($nums) < 5)
{
$random = rand(1,50);
if( isset($keyIndex[$random] ) )
continue;
$nums[] = $random;
$keyIndex[$random] = true;
}
Heuuuu... pour moi c'est pas du tout simple ce que tu me proposes là. ^^
Je comprends pas ce que ton code fait à vrai dire. :s
Si tu peux m'expliquer ça s'il te plait ?
:noob:
Je vois que tu mets en tableau les valeurs des 5 variables $numX, que tu as un autre tableau dont je ne comprends pas à quoi il sert.
Et ensuite je suis pas perdu, je comprends pas ce que ça fait. ![]()
Et si on jouait au jeu "que fait ce code ?" plutôt .
Étape numéro 1 :
À ton avis, à quoi sert la variable keyindex introduite par _skip ? ![]()
Bon, d'après ce que je comprends :
- Les variable $nums et $KeyIndex sont des tableaux, vides au départ.
- On ouvre une boucle while ou tant qu'on a pas 5 $nums ça continue de boucler.
- Dans la boucle on sort un numéro du random.
- Si le numéro existe on continue. Mais là j'ai pas l'habitude de ce genre de truc donc je capte pas ce que fout le $KeyIndex. Enfin, disons plutôt que je pense qu'il sert à conserver la valeur pour être une clé de tableau.
Mais ça manque de commentaires...
Enfin, on colle $random en valeur pour le tableau $nums, et on fixe à true $KeyIndex[$random].
Moi j'aime pas optimiser un code quand je suis meme pas sur de savoir ce qu'il doit reellement faire.
C'est quoi le vrai objectif de ton code au juste ?
Non pas que je ne comprends pas ton algorithme ni ce qui se passe mais ca reste trop flou pour savoir si ce que tu fais est vraiment intelligent au lieu de tout simplement revoir le probleme de facon differente.... or ce qui manque c'est l'enonce du probleme la.
Ah pardon, je pensais l'avoir mis.
L'objectif est : Sortir 5 nombres, sans doublon.
Non ca j'ai compris, mais c'est vraiment le seul truc qu'on a a savoir ? Avant d'optimiser un code on tente d'optimiser l'algorithme autour.
Sinon c'est bon tu as compris l'exemple de _skip maintenant ?
Bah oui c'était tout. ^^
Ma curiosité me poussait à me demander comment j'aurais fait si j'avais dû faire la même chose mais avec 10 000 nombres.
On m'a donné ça aussi comme méthode :
<?php
function randperm($max) {
$perm = range(1,$max);
for($cpt = $max-1; $cpt > 0; $cpt--) {
$nb = rand(1,$cpt);
$tmp = $perm[$cpt];
$perm[$cpt] = $perm[$nb];
$perm[$nb] = $tmp;
}
return($perm);
}
$perm = randperm(50);
for($cpt = 1; $cpt < 6; $cpt++) {
echo ' '.$perm[$cpt]."<br />";
}
?>
Non, dans l'exemple donné j'ai du mal avec ça =>
if( isset($keyIndex[$random] ) )
continue;
$keyIndex[$random] = true;
Il colle à la variable la valeur true après le if. Je l'aurais mis avant.
Parce que $KeyIndex[$random] , il contient quoi au moment où le if se déclenche ?
Un boolean !
Si cette ligne retourne true ca veut dire que ce nombre a deja ete randommise donc on recommence la boucle sans se poser plus de questions. Sinon ca veut dire qu'il n'existe pas donc on concatene ce dernier avec le tableau de sortie nums et on met l'entree a keyIndex[random] a true.
Il y avait deux choses moches dans ta solution de depart :
- cote algorithmique tu devais TOUJOURS tout refaire si seulement un resultat avait un doublon. Ce sont des calculs refaient pour rien
- cote code, ton code etait assez fige (seulement 5 random possibles), et avec un while qui tient sur plusieurs lignes erk.
Ma solution finale serait par exemple de donner en parametre le nombre de tirages differents que tu veux recevoir en resultat, comme ca tu as vraiment un code dynamique que tu pourras reutiliser par la suite.
Ce qui est difficile à comprendre avec l'index, c'est que j'utilise un tableau PHP en sachant qu'au niveau structure de données c'est une map triée et pas réellement un array au sens C/C++/java.
$array = array();
isset( $array[5] ) //return false, la clé 5 n'existe pas;
$array[5] = 'choucroute'; //je la définis et je reteste
isset( $array[5] ) //return true, la clé 5 existe avec la valeur "choucroute";
Avoir une seule structure qui fait liste, map, pile et qui porte le nom de tableau, forcément ça porte à confusion!
D'accord. Merci à vous pour les explications. ![]()
<?php
$count = 0;
$nums = array();
while($count != 5) {
$rand = mt_rand(1, 50);
if(!in_array($rand, $nums)) {
$nums[] = $rand;
$count++;
}
}
Après 5000 intération sur le code de _skip et celui ci, il s'avère que c'est aussi rapide (ou aussi lent). Par contre, c'est un peu plus élégant à mon goût.
Merci pour la variante, que je comprends mieux d'ailleurs. ![]()
""Vous aussi, commandez dès aujourd'hui notre livre "les grands mystères de PHP" volume 5 pour la modique somme de dix-neuf euros quatre-vingts quinze hors taxe.""
Non sérieux je comprends absolument pas pourquoi un code qui fait 2500 vérifications par itération en moyenne est aussi rapide qu'un autre qui fait un simple accès à une clé sur une map ordonnée (qui au pire serait donc une implémentation en arbre voire une linkedhashmap).
Ca me conforte bien dans le peu d'estime que j'ai de ce langage.
Vous connaissez mal PHP du coup les seules choses que vous voyez ce sont les choses qui ne vous conviennent pas :/
Tres vraisemblablement parce que in_array a ete compile et optimise a l'avance au lieu de passer par des mecanismes paralleles en l'apparence plus intelligents.
PHP n'est pas toujours compilable et compile si je me rappelle bien, seuls certaines framework comme Zend le permettent non ? (question ouverte)
deepblue Voir le profil de deepblue
Posté le 20 décembre 2011 à 09:00:47 Avertir un administrateur
Vous connaissez mal PHP du coup les seules choses que vous voyez ce sont les choses qui ne vous conviennent pas :/
C'est surtout que la documentation est rare ou inexistante sur tout ce qui devient un tant soit peu pointu en terme de performance.
On dirait que la difference est l'utilisation d'un tableau a la place d'un ABR. Certes un ABR a une complexite de O(log(n)) sur l'operation find, mais tres souvent la constante qui est cache dans la notation big-O est consequente.
Le tableau contient 5000 valeurs, qui sont des entiers de 32 bit (certainement). Ca represente de l'ordre de 20K octet qui tiennent parfaitement dans un cache L1. Maintenant, si l'ABR est implemente connement avec un arbre et deux pointeurs pour les fils qui ne sont pas stocke de facon continue en memoire. Tu te retrouve a devoir acceder une ligne de cache pour chaque access en memoire et la structure consomme 64 octets par valeur, ce qui est approximativement 320K octets qui ne tient pas en cache L1.
Je ne parle meme pas du fait que la cherche dans un tableau est tres adapte aux pipeline des processeurs et peut etre accelerer par les instructions vectoriel du processeur alors qu'un ABR ne l'est probablement pas.
Apres tout ca n'a peut etre rien a voir, et ca m'etonnerait que les hashmap de php soit aussi mal implementer que ca. Mais avoir une difference de complexite et avoir une difference de performance sont deux choses differentes, souvent correler, mais pas toujours.