PHP rand()排除某些数字

PHP rand()排除某些数字,php,Php,我有这个: <?php $n = rand(1,1600); echo $n ?> 我想从随机数中排除23415787631274和其他数字。我该怎么做呢?像这样试试 do { $n = rand(1,1600); } while(in_array($n, array(234, 1578 ,763 , 1274 )); echo $n; 检查该数字是否是您不想要的,如果是,请获取一个新的随机数 function getRandomNumber() {

我有这个:

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

我想从随机数中排除23415787631274和其他数字。我该怎么做呢?

像这样试试

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

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

检查该数字是否是您不想要的,如果是,请获取一个新的随机数

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

    return $n;
}

您可以创建一个包含有效数字的数组


然后,您的随机数生成应该将索引返回到该数组中。

如果您没有太多的数字要排除,则如果您发现不需要的数字,只需重试就会更容易、更快:

$n=0;
而(在数组中($n,数组(023415787631274))){
$n=兰特(11600);
}
echo$n;

或避免使用随机(可能无限)运行时间进行循环:

/**
 * 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;
}
/**
*返回一个介于$min和$max(含)之间的随机整数,并
*排除$exarr中的整数,如果没有此类数字,则返回false
*存在。
* 
*假设$exarr按递增顺序排序,每个
*元素应该是唯一的。
*/
函数random_exclude($min、$max、$exarr=array()){
如果($max-count($exarr)<$min){
返回false;
}
//$pos是随机数将采用的位置
//所有允许的位置
$pos=rand(0,$max-$min-count($exarr));
//$num是随机数
$num=$min;
//当$pos>0时,转到下一个位置
//如果下一个位置可用,则减小
对于($i=0;$i=$dif){
$num+=$dif;
//-1因为我们现在处于被排除的位置
$pos-=$dif-1;
}否则{
//否则,返回自由位置
返回$num+$pos;
}
}
//返回数字加上我们仍然要去的未平仓
返回$num+$pos;
}

此函数选择一个随机位置并遍历排除数组以查找自由位置。它的运行时间取决于要排除的数量。如果要排除某些范围,可能需要调整算法以将其考虑在内。

另一种解决方案如下:

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

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

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

始终使用加密强算法生成随机数:

/**
 * @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)));
我还建议在使用多个PHP版本时使用该库以实现兼容性。

随着“黑名单”整数的数量接近全范围整数的数量,越来越有必要采纳@regenschein的建议

非迭代方法可能如下所示:

$range = range(1, 1600);
$blacklist = [234, 1578, 763, 1274]; // 4 blacklisted versus 1600 full range is NOT compelling
$valids = array_diff($range, $blacklist);
echo array_values($valids)[rand(0, count($valids) - 1)];
// or
echo $valids[array_rand($valids)];
// the two approaches use different randomizers
或者,如果你也喜欢洗牌,你可以:

$blacklist = [234, 1578, 763, 1274];
$range = range(1, 1600);
$valids = array_diff($range, $blacklist);
shuffle($valids);
echo $valids[0];
*注意
array_diff()
如果您想传递多个黑名单数组,那么它特别有用——只需用逗号分隔它们

例如:

var_export($valids = array_diff(range(1, 100), range(5, 50), range(61, 99), [55]));
输出:

array (
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 4,
  50 => 51,
  51 => 52,
  52 => 53,
  53 => 54,
  55 => 56,
  56 => 57,
  57 => 58,
  58 => 59,
  59 => 60,
  99 => 100,
)

我知道这有点陈旧,但我认为op尝试做的是洗牌整数。如果是这样,下面的方法更好

$array = array(1,2,3,4,5,6,7);
shuffle($array);

此代码将不重复地随机化数组确切元素的顺序,并返回数组内部的结果。

它将检查生成的数字是否在数组中,如果它们存在,则再次转到doloop@ClaudioLudovicoPanetta-为什么要让它递归,如果while循环工作得很好?更新了我的while条件,这样添加新的数字就更容易了。错过结束)在whiled上不要使用rand,使用mt_rand,或者如果你来自PHP7,使用更好的random_int。虽然这个循环工作得很好,但在循环中使用赋值总是让我害怕:|@emix现在没关系了,因为
rand()
mt_rand()的同义词。
使用别名时会得到额外的操作码。不过,
random\u int
要好得多。不要使用rand!使用,或者如果您来自PHP7,则更好。这是迄今为止最干净的解决方案-所有其他解决方案都是递归的或使用循环,从理论上讲,这些循环可能是无止境的,也会导致糟糕的编程。
$array = array(1,2,3,4,5,6,7);
shuffle($array);