2013-06-14 16 views
6

mam to:PHP rand() wykluczyć niektóre numery

<?php $n = rand(1,1600); echo $n ?> 

chcę wykluczyć z liczb losowych powiedzmy, 234, 1578, 763, 1274 i inne numery. Jak to zrobić?

+1

Nie używaj rand! Użyj [mt_rand] (http://php.net/mt_rand) lub lepiej [random_int] (http://php.net/random_int), jeśli pochodzisz z PHP7. –

Odpowiedz

10
<?php 

while(in_array(($n = rand(1,1600)), array(234, 1578 ,763 , 1274))); 
+1

Nie używaj randu, używaj mt_rand lub lepiej random_int jeśli pochodzisz z PHP7. –

8

Spróbuj jak to

do { 
    $n = rand(1,1600); 

} while(in_array($n, array(234, 1578 ,763 , 1274)); 
echo $n; 
+0

to sprawdzi, czy wygenerowana liczba jest w tablicy, czy nie, jeśli są obecne, to znowu zrobi pętlę do-while – Gautam3164

+0

nvm, właśnie uświadomiłem sobie, co powiedziałem, że było złe – Menztrual

5

Sprawdź, czy numer jest jeden, że nie chcesz, jeśli jest dostać nową liczbę losową.

function getRandomNumber() { 
    do { 
     $n = mt_rand(1,1600); 
    } while(in_array($n, array(234,1578, 763, 1274))); 

    return $n; 
} 
+0

Dlaczego nie rekursywne? –

+1

@ClaudioLudovicoPanetta - dlaczego robi się rekurencyjny, czy pętla działa perfekcyjnie? – andrewsi

+0

@andrewsi, ponieważ rekursywna jest zawsze chłodniejsza :-P –

-1

Można utworzyć tablicę z prawidłowymi liczbami.

Następnie generowanie liczb losowych powinno zwrócić indeks do tej tablicy.

0

Jeśli nie masz zbyt wiele liczb, aby wykluczyć, że łatwiej i szybciej jest po prostu ponownie, jeśli okaże się liczbę niechcianych:

$n = 0; 
while (in_array($n, array(0, 234, 1578 ,763 , 1274))) { 
    $n = rand(1,1600); 
} 

echo $n; 
0

Albo uniknąć pętli z random (ewentualnie nieskończony) czas działania:

/** 
* Returns a random integer between $min and $max (inclusive) and 
* excludes integers in $exarr, returns false if no such number 
* exists. 
* 
* $exarr is assumed to be sorted in increasing order and each 
* element should be unique. 
*/ 
function random_exclude($min, $max, $exarr = array()) { 

    if ($max - count($exarr) < $min) { 
     return false; 
    } 

    // $pos is the position that the random number will take 
    // of all allowed positions 
    $pos = rand(0, $max - $min - count($exarr)); 

    // $num being the random number 
    $num = $min; 

    // while $pos > 0, step to the next position 
    // and decrease if the next position is available 
    for ($i = 0; $i < count($exarr); $i += 1) { 

     // if $num is on an excluded position, skip it 
     if ($num == $exarr[$i]) { 
      $num += 1; 
      continue; 
     } 

     $dif = $exarr[$i] - $num; 

     // if the position is after the next excluded number, 
     // go to the next excluded number 
     if ($pos >= $dif) { 
      $num += $dif; 

      // -1 because we're now at an excluded position 
      $pos -= $dif - 1; 
     } else { 
      // otherwise, return the free position 
      return $num + $pos; 
     } 
    } 

    // return the number plus the open positions we still had to go 
    return $num + $pos; 
} 

Ta funkcja wybiera przypadkową pozycję i przechodzi do tablicy wykluczeń, aby znaleźć wolną pozycję. Czas działania zależy od liczby liczb, które należy wykluczyć. Jeśli chcesz wykluczyć określone zakresy, możesz dostosować algorytm, aby to uwzględnić.

0

Innym rozwiązaniem mogłoby być następujące:

function random_number($min, $max, $exclude) 
{ 
     $number = rand($min, $max); 

    if(in_array($number, $exlude)) 
    { 
     random_number($min, $max, $exlude); 
    } else { 
     return $number; 
    } 
} 

$number = random_number(1,10, [2,5,6]); 
0

Zawsze używać kryptograficznie silne algorytmy generowania liczb losowych:

/** 
* @param int $from  From number 
* @param int $to  To number 
* @param array $excluded Additionally exclude numbers 
* @return int 
*/ 
function randomNumber($from, $to, array $excluded = []) 
{ 
    $func = function_exists('random_int') ? 'random_int' : 'mt_rand'; 

    do { 
     $number = $func($from, $to); 
    } while (in_array($number, $excluded, true)); 

    return $number; 
} 

var_dump(randomNumber(1, 100)); 
var_dump(randomNumber(1, 10, [5, 6, 7, 8])); 
var_dump(randomNumber(1, 100, range(10, 90))); 
Powiązane problemy