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ć?
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ć?
<?php
while(in_array(($n = rand(1,1600)), array(234, 1578 ,763 , 1274)));
Nie używaj randu, używaj mt_rand lub lepiej random_int jeśli pochodzisz z PHP7. –
Spróbuj jak to
do {
$n = rand(1,1600);
} while(in_array($n, array(234, 1578 ,763 , 1274));
echo $n;
to sprawdzi, czy wygenerowana liczba jest w tablicy, czy nie, jeśli są obecne, to znowu zrobi pętlę do-while – Gautam3164
nvm, właśnie uświadomiłem sobie, co powiedziałem, że było złe – Menztrual
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;
}
Dlaczego nie rekursywne? –
@ClaudioLudovicoPanetta - dlaczego robi się rekurencyjny, czy pętla działa perfekcyjnie? – andrewsi
@andrewsi, ponieważ rekursywna jest zawsze chłodniejsza :-P –
Można utworzyć tablicę z prawidłowymi liczbami.
Następnie generowanie liczb losowych powinno zwrócić indeks do tej tablicy.
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;
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ć.
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]);
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)));
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. –