从不重复且不在数组中的特定范围生成x个随机数

时间:2019-11-10 18:28:34

标签: php

如何生成数字列表(18个数字),它们的范围是从1到36(包括1和36),并且生成的数字必须与数组中存在的数字不同

示例: 数组编号:27、31、18、4、15、6

我需要输出18个不在上面的数组中的随机数,并且这些数字不能重复。

输出I应该得到:17、21、14、28、7、8、12、20、3、5、16、2、36、11、26、13、24、35

function randomGen($min, $max, $quantity) {
    $exluding_array = [1,2,3,4,5,6,7,8,9,10];
    $numbers = range($min, $max);
    shuffle($numbers);
    if(range($min, $max) === $exluding_array) {
        return "no";
    } else {
        return array_slice($numbers, 0, $quantity);
    }
}

使用此代码,我得到的随机数没有重复项,但是返回的数字可以是exluding_array中的数字。

3 个答案:

答案 0 :(得分:1)

切片前,您可以使用array_diff从生成的excluding_array中删除所有数量的numbers

function randomGen($min, $max, $quantity) {
    $excluding_array = [1,2,3,4,5,6,7,8,9,10];
    $numbers = range($min, $max);
    // Remove unwanted numbers
    $numbers = array_diff($numbers, $excluding_array);
    shuffle($numbers);
    if (count($numbers) < $quantity) {
        return "no";
    } else {
        return array_slice($numbers, 0, $quantity);
    }
}

注意:尽管在这种情况下返回“ no”似乎不是最好的解决方案,但我也改善了您的健全性检查。您可能想要抛出一个异常,如vivek_23所示。

Sample on PHP sandbox

答案 1 :(得分:0)

另一种方法是,您可以array_flip $ except数组并检查$ numbers中是否存在这些数字。如果找到它们,我们将跳过它们,否则将其包含在最终数组中。

如果我们产生的数字不及Exception,我们也可以抛出$quantity

<?php

function randomGen($min, $max, $quantity) {
    $exluding_array = [1,2,3,4,5,6,7,8,9,10];
    $exluding_array = array_flip($exluding_array);
    $numbers = range($min, $max);
    shuffle($numbers);
    $filtered_numbers = [];
    foreach($numbers as $curr_number){
        if(isset($exluding_array[$curr_number])) continue;
        $filtered_numbers[] = $curr_number;
    }

    if(count($filtered_numbers) < $quantity) throw new Exception("Can't generate numbers with the given quantity and range.");

    return array_slice($filtered_numbers, 0, $quantity);
}


print_r(randomGen(1,36,10));

演示: https://3v4l.org/mUi8A

您还可以使此函数的被调用者实现try-catch块,以优雅地处理异常。

答案 2 :(得分:0)

我将使用array_filter来过滤排除的数字:

function randomGen(int $min, int $max, int $quantity, array $excluded = []): array
{
  $result = array_filter(range($min, $max), static function ($val) use ($excluded) {
    return !in_array($val, $excluded, true);
  });
  shuffle($result);
  return array_slice($result, 0, $quantity);
}

$result = randomGen(1, 36, 10, range(1, 10));

演示:https://3v4l.org/nkbTK