ho questo:PHP rand() escludere certi numeri
<?php $n = rand(1,1600); echo $n ?>
voglio escludere dai numeri casuali diciamo 234, 1578, 763, 1274 e altri numeri. Come potrei farlo?
ho questo:PHP rand() escludere certi numeri
<?php $n = rand(1,1600); echo $n ?>
voglio escludere dai numeri casuali diciamo 234, 1578, 763, 1274 e altri numeri. Come potrei farlo?
<?php
while(in_array(($n = rand(1,1600)), array(234, 1578 ,763 , 1274)));
Non usare rand, usa mt_rand, o meglio random_int se vieni da PHP7. –
Prova come questo
do {
$n = rand(1,1600);
} while(in_array($n, array(234, 1578 ,763 , 1274));
echo $n;
controllerà se il numero generato è in array o no, se sono presenti, quindi goto il ciclo do-while – Gautam3164
nvm, ho appena realizzato quello che ho detto che era sbagliato – Menztrual
Verificare se il numero è uno che non si vuole, se si tratta di ottenere un nuovo numero casuale.
function getRandomNumber() {
do {
$n = mt_rand(1,1600);
} while(in_array($n, array(234,1578, 763, 1274)));
return $n;
}
Perché non ricorsivo? –
@ClaudioLudovicoPanetta - perché renderlo ricorsivo, se un ciclo while funziona perfettamente? – andrewsi
@andrewsi perché ricorsivo è sempre più fresco :-P –
È possibile creare un array con numeri validi.
Quindi, la generazione del numero casuale deve restituire l'indice in tale matrice.
Se non si dispone di troppi numeri da escludere, è più facile e più veloce per solo riprovare se si trova un numero indesiderato:
$n = 0;
while (in_array($n, array(0, 234, 1578 ,763 , 1274))) {
$n = rand(1,1600);
}
echo $n;
O evitare di fare loop con casuale (possibilmente infinita) durata:
/**
* 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;
}
Questa funzione sceglie una posizione casuale e percorre l'array di esclusione per trovare la posizione libera. Il tempo di esecuzione dipende dalla quantità di numeri da escludere. Se si desidera escludere determinati intervalli, è possibile adattare l'algoritmo per tenerne conto.
Un'altra soluzione per questo potrebbe essere il seguente:
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]);
Utilizzare sempre gli algoritmi di crittografia forte per la generazione di numeri casuali:
/**
* @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)));
Non usare rand! Usa [mt_rand] (http://php.net/mt_rand), o meglio [random_int] (http://php.net/random_int) se vieni da PHP7. –