recherche

Maison  >  Questions et réponses  >  le corps du texte

Générer des nombres aléatoires uniques dans une certaine plage

J'ai besoin de générer des nombres uniques aléatoires dans une certaine plage, comment puis-je faire cela ? Je peux générer des nombres aléatoires par

generator:
$arr = [];
$x = rand($min, $max);
$len = count($arr);
$flag = 0;
for($i = 0; $i < $len; $i++)
{
 if ($flag === 1)
   goto generator;
 if ($x === $arr[$i])
   $flag = 1;
}
$arr[$index] = $x;
$index++; 
goto generator;

Je sais que ce code est terrible, je dois donc améliorer le code de ma version ! aide!

Exemple : Si je dois générer 3 nombres entre 1 et 15, ils devraient être comme 5, 9, 1, mais pas 3, 1, 2 [en 1 - 3 (les nombres que je veux générer)]

P粉087951442P粉087951442439 Il y a quelques jours553

répondre à tous(2)je répondrai

  • P粉668146636

    P粉6681466362023-10-16 18:17:22

    $len = 10;   // total number of numbers
    $min = 100;  // minimum
    $max = 999;  // maximum
    $range = []; // initialize array
    foreach (range(0, $len - 1) as $i) {
        while(in_array($num = mt_rand($min, $max), $range));
        $range[] = $num;
    }
    print_r($range);

    J'aimerais savoir en quoi la réponse acceptée diffère de ma réponse. Il est à noter qu'un mélange des deux peut être avantageux ; en effet, voici une fonction qui utilise conditionnellement l'un ou l'autre en fonction de certaines valeurs :

    # The accepted answer
    function randRange1($min, $max, $count)
    {
        $numbers = range($min, $max);
        shuffle($numbers);
        return array_slice($numbers, 0, $count);
    }
    
    # My answer
    function randRange2($min, $max, $count)
    {
        $i = 0;
        $range = array();
        while ($i++ < $count) {
            while(in_array($num = mt_rand($min, $max), $range));
            $range[] = $num;
        }
        return $range;
    }
    
    echo 'randRange1: small range, high count' . PHP_EOL;
    $time = microtime(true);
    randRange1(0, 9999, 5000);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;
    
    echo 'randRange2: small range, high count' . PHP_EOL;
    $time = microtime(true);
    randRange2(0, 9999, 5000);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;
    
    echo 'randRange1: high range, small count' . PHP_EOL;
    $time = microtime(true);
    randRange1(0, 999999, 6);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;
    
    echo 'randRange2: high range, small count' . PHP_EOL;
    $time = microtime(true);
    randRange2(0, 999999, 6);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;

    Résultat :

    randRange1: small range, high count
    0.019910097122192
    
    randRange2: small range, high count
    1.5043621063232
    
    randRange1: high range, small count
    2.4722430706024
    
    randRange2: high range, small count
    0.0001051425933837

    La réponse acceptée est définitivement optimale si vous utilisez une plage plus petite et un nombre plus élevé de valeurs de retour ; cependant, comme je m'y attendais, des plages plus grandes et des comptes plus petits prendront plus de temps. Pour arriver à la réponse acceptée, elle doit stocker toutes les valeurs possibles dans le gamme. Vous courez même le risque de dépasser la limite de mémoire de PHP. Évaluer le rapport entre la portée et le nombre et choisir conditionnellement un hybride de générateurs serait le meilleur des deux mondes.

    répondre
    0
  • P粉180844619

    P粉1808446192023-10-16 11:11:30

    Tableau avec des plages de nombres dans un ordre aléatoire :

    $numbers = range(1, 20);
    shuffle($numbers);

    Fonction d'emballage :

    function UniqueRandomNumbersWithinRange($min, $max, $quantity) {
        $numbers = range($min, $max);
        shuffle($numbers);
        return array_slice($numbers, 0, $quantity);
    }

    Exemple :

    <?php
    print_r( UniqueRandomNumbersWithinRange(0,25,5) );
    ?>

    Résultat :

    Array
    (
        [0] => 14
        [1] => 16
        [2] => 17
        [3] => 20
        [4] => 1
    )

    répondre
    0
  • Annulerrépondre