Как сгенерировать массив наборов случайных чисел в PHP? - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь найти лучший способ создать массив наборов случайно выбранных чисел из диапазона. Так, например, у меня есть диапазон номеров, из которых можно выбрать: 1-100. Я хочу сгенерировать X наборов из 5 из этих чисел БЕЗ ДУБЛИКАТОВ. Итак, я хочу сгенерировать что-то вроде:

[3, 24, 32, 49, 68]

[2, 18, 43, 76, 98]

[10, 12, 23, 45, 67]

[5, 56, 64, 72, 90]

...

Я знаю, как генерировать случайные числа из диапазона один раз, я просто застрял на этом X раз без возможности дублирования наборов.

Ответы [ 2 ]

1 голос
/ 30 января 2020

Один из способов решения этой проблемы - просто сгенерировать желаемый диапазон $arr = range(1, 100), затем перемешать его, чтобы рандомизировать shuffle($arr), затем разбить его на части, чтобы получить наборы 5 $sets = array_chunk($arr, 5).

Итак, окончательный ответ :

$arr = range(1, 100); // gives us an array of 100 integers 1-100
shuffle($arr); // randomly orders those integers
$sets = array_chunk($arr, 5); // creats an array of arrays of sets of 5 integers

foreach ($sets as $set) {
    echo implode(',', $set), "\n";
}

Дает вам что-то вроде ...

14,24,60,95,86
47,54,10,77,3
11,22,88,80,39
72,46,81,78,59
63,98,52,82,8
79,34,43,13,41
67,33,75,1,2
4,57,84,73,17
32,55,35,18,70
64,85,100,93,71
25,19,26,20,76
99,89,7,87,91
37,97,68,27,5
74,48,65,61,58
45,31,9,30,21
16,56,50,96,90
92,40,6,44,23
28,94,38,83,29
36,62,51,66,15
12,69,49,42,53

Альтернативная реализация

Еще один способ решения этой проблемы, который не требует записи всего массива в память сразу и затем случайным образом прибегая к ней, будет использовать хэш-набор, который отслеживает все случайно сгенерированные целые числа для предотвращения дублирования. Это дает нам один и тот же точный результат, за исключением того, что мы выполняем генерацию и сортировку случайных чисел за один шаг вместо двух. Таким же образом вы также можете выполнить чанкинг в одном и том же шаге.

Имейте в виду, однако, что это решение технически медленнее, поскольку оно в неограниченное время (мы должны продолжайте гадать, если число уже существует).

Я собираюсь использовать генератор для реализации этого решения, поскольку его легче написать, чем шаблон Iterator.

function randomizeIntegerXRangeChunked($start, $end, $chunks = 5): Generator
{
    $inSet = []; // track the integers already in the set

    for ($i = $start, $c = 0; $i <= $end; $i++) {
        /* solution is in unbounded time */
        while (isset($inSet[($n = mt_rand($start, $end))]));

        $inSet[$n] = true;

        yield $c => $n;

        if (!($i % $chunks)) {
            $c++;
        }
    }
}


$arr = [];

foreach (randomizeIntegerXRangeChunked(1, 100, 5) as $chunk => $int) {

    $arr[$chunk][] = $int;

}

var_dump($arr);

Вывод будет похож на ...

array(20) {
  [0]=>
  array(5) {
    [0]=>
    int(43)
    [1]=>
    int(52)
    [2]=>
    int(38)
    [3]=>
    int(73)
    [4]=>
    int(55)
  }
  [1]=>
  array(5) {
    [0]=>
    int(59)
    [1]=>
    int(3)
    [2]=>
    int(71)
    [3]=>
    int(47)
    [4]=>
    int(50)
  }
  [2]=>
  array(5) {
    [0]=>
    int(54)
    [1]=>
    int(19)
    [2]=>
    int(60)
    [3]=>
    int(40)
    [4]=>
    int(5)
  }
  [3]=>
  array(5) {
    [0]=>
    int(26)
    [1]=>
    int(46)
    [2]=>
    int(93)
    [3]=>
    int(80)
    [4]=>
    int(63)
  }
  [4]=>
  array(5) {
    [0]=>
    int(18)
    [1]=>
    int(45)
    [2]=>
    int(98)
    [3]=>
    int(1)
    [4]=>
    int(72)
  }
  [5]=>
  array(5) {
    [0]=>
    int(37)
    [1]=>
    int(97)
    [2]=>
    int(15)
    [3]=>
    int(68)
    [4]=>
    int(8)
  }
  [6]=>
  array(5) {
    [0]=>
    int(34)
    [1]=>
    int(14)
    [2]=>
    int(33)
    [3]=>
    int(24)
    [4]=>
    int(65)
  }
  [7]=>
  array(5) {
    [0]=>
    int(4)
    [1]=>
    int(16)
    [2]=>
    int(13)
    [3]=>
    int(41)
    [4]=>
    int(86)
  }
  [8]=>
  array(5) {
    [0]=>
    int(95)
    [1]=>
    int(12)
    [2]=>
    int(44)
    [3]=>
    int(66)
    [4]=>
    int(83)
  }
  [9]=>
  array(5) {
    [0]=>
    int(67)
    [1]=>
    int(48)
    [2]=>
    int(91)
    [3]=>
    int(27)
    [4]=>
    int(79)
  }
  [10]=>
  array(5) {
    [0]=>
    int(56)
    [1]=>
    int(25)
    [2]=>
    int(2)
    [3]=>
    int(64)
    [4]=>
    int(78)
  }
  [11]=>
  array(5) {
    [0]=>
    int(57)
    [1]=>
    int(17)
    [2]=>
    int(74)
    [3]=>
    int(42)
    [4]=>
    int(69)
  }
  [12]=>
  array(5) {
    [0]=>
    int(96)
    [1]=>
    int(20)
    [2]=>
    int(9)
    [3]=>
    int(28)
    [4]=>
    int(7)
  }
  [13]=>
  array(5) {
    [0]=>
    int(30)
    [1]=>
    int(75)
    [2]=>
    int(21)
    [3]=>
    int(6)
    [4]=>
    int(89)
  }
  [14]=>
  array(5) {
    [0]=>
    int(51)
    [1]=>
    int(36)
    [2]=>
    int(62)
    [3]=>
    int(58)
    [4]=>
    int(23)
  }
  [15]=>
  array(5) {
    [0]=>
    int(85)
    [1]=>
    int(32)
    [2]=>
    int(100)
    [3]=>
    int(61)
    [4]=>
    int(49)
  }
  [16]=>
  array(5) {
    [0]=>
    int(39)
    [1]=>
    int(87)
    [2]=>
    int(76)
    [3]=>
    int(70)
    [4]=>
    int(22)
  }
  [17]=>
  array(5) {
    [0]=>
    int(88)
    [1]=>
    int(77)
    [2]=>
    int(10)
    [3]=>
    int(99)
    [4]=>
    int(53)
  }
  [18]=>
  array(5) {
    [0]=>
    int(94)
    [1]=>
    int(35)
    [2]=>
    int(92)
    [3]=>
    int(90)
    [4]=>
    int(84)
  }
  [19]=>
  array(5) {
    [0]=>
    int(81)
    [1]=>
    int(82)
    [2]=>
    int(31)
    [3]=>
    int(29)
    [4]=>
    int(11)
  }
}
0 голосов
/ 30 января 2020

Вы можете попробовать это так же.

// Array
$NumberArray = array();
$TempArray = array(); // Used for storing randoms while we check via if statement.

// Loop 5 times.
for ($x=0; $x<=4; $x++) {

    // Random Number 1-100
    $RandomNumber = rand(1,100);

    // We can use Array Push to add to the array and check using in_array.
    array_push($TempArray, $RandomNumber);

    // Check first thing in temp array and see if its already in number array. (If not then push)
    if (!in_array(reset($TempArray), $NumberArray)) { 
        array_push($NumberArray, reset($TempArray)); // Add to NumberArray
        // Clear Temp Array
        $TempArray = array();
    } else {
        // Add to the loop
        $x--;
    }

}

print_r($NumberArray);

Это выдает массив, подобный такому:

Array
(
    [0] => 32
    [1] => 26
    [2] => 59
    [3] => 96
    [4] => 34
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...