PHP随机数

时间:2010-08-18 14:16:44

标签: php arrays random

我想从区间1,49中抽取一个随机数,但我想添加一个数字作为例外(比方说44),我不能使用回合(兰德(1,49))。所以我决定制作49个数字(1-49),unset[$aray[44]]并应用array_rand

的数组

现在我想从区间[$ left,49]中绘制一个数字,我怎么能使用之前使用的相同数组呢?数组现在错过了值44。

3 个答案:

答案 0 :(得分:3)

函数选择将数组作为参数,包含您已选择的所有数字。然后它将在该数组中的不是的开头和结尾之间选择一个数字。它会将此数字添加到该数组中并返回该数字。

function pick(&$picked, $start, $end) {

    sort($picked);

    if($start > $end - count($picked)) {
        return false;
    }

    $pick = rand($start, $end - count($picked));
    foreach($picked as $p) {
        if($pick >= $p) {
            $pick += 1;
        } else {
            break;
        }
    }

    $picked[] = $pick;

    return $pick;
}

此函数将有效地获取一个不在数组中的随机数,并且永远不会无限期地退回!

要像你想要的那样使用它:

$array = array(44); // you have picked 44 for example
$num = pick($array, 1, 49); // get a random number between 1 and 49 that is not in $array  

// $num will be a number between 1 and 49 that is not in $arrays

该功能如何运作


假设你得到1到10之间的数字。你选择了两个数字(例如2和6)。这将使用rand:rand(1, 8)选择1到(10减2)之间的数字。

然后会检查已挑选的每个号码并检查号码是否更大。

例如:

If rand(1, 8) returns 2. 
  It looks at 2 (it is >= then 2 so it increments and becomes 3)
  It looks at 6 (it is not >= then 6 so it exits the loop)
  The result is: 3

If rand(1, 8) returns 3
  It looks at 2 (it is >= then 2 so it increments and becomes 4)
  It looks at 6 (it is not >= then 6 so it exits the loop)
  The result is 4

If rand(1, 8) returns 6
  It looks at 2 (it is >= then 2 so it increments and becomes 7)
  It looks at 6 (it is >= then 6 so it increments and becomes 8)
  The result is: 8

If rand(1, 8) returns 8
  It looks at 2 (it is >= then 2 so it increments and becomes 9)
  It looks at 6 (it is >= then 6 so it increments and becomes 10)
  The result is: 10

因此返回1到10之间的随机数,它不会是2或6.

我很久以前实施了这项工作,以便将地雷随机地放置在一个二维阵列中(因为我想要随机地雷,但我想保证该地区的地雷数量为一定数量)

答案 1 :(得分:0)

为什么不检查您的例外:

function getRand($min, $max) {
    $exceptions = array(44, 23);
    do {
        $rand = mt_rand($min, $max);
    } while (in_array($rand, $exceptions));
    return $rand;
}

请注意,如果您提供强制mt_rand强制返回异常字符的最小值和最大值,则可能会导致无限循环。因此,如果你调用getRand(44,44);,虽然没有意义,但会导致无限循环...(并且你可以避免函数中有一点逻辑的无限循环(检查至少有一个非异常值)范围$min$max)...

另一个选择是使用循环构建数组:

function getRand($min, $max) {
    $actualMin = min($min, $max);
    $actualMax = max($min, $max);
    $values = array();
    $exceptions = array(44, 23);
    for ($i = $actualMin; $i <= $actualMax; $i++) {
        if (in_array($i, $exceptions)) {
            continue;
        }
        $values[] = $i;
    }
    return $values[array_rand($values)];
}

答案 2 :(得分:-1)

最简单的解决方案是只搜索从minmax - number of exceptions的随机数。然后只需将结果加1,使每个异常低于结果。

function getRandom($min, $max)
{
  $exceptions = array(23, 44); // Keep them sorted or you have to do sort() every time
  $random = rand($min, $max - count($exceptions));
  foreach ($exceptions as $ex)
  {
    if ($ex > $random) break;
    ++$random;
  }
  return $random;
}

运行时应为O(1 + n),n为低于结果的异常数。