Как создать совершенно уникальный набор номеров в Perl - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь написать сценарий perl, который создает полный набор уникальных случайных чисел.

скажем, у меня есть числа от 1 до 50 Я хочу создать 5 наборов с 5 уникальными номерами на набор, но не повторять число в любом наборе. Приведенный ниже скрипт генерирует числа случайно и уникально в каждой строке, но числа повторяются в других строках. Таким образом, текущий результат будет выглядеть примерно так:

20  11  28   5  10
 5  23  20  42  14
 1  38   6   7   9
25   0  16  35  17
23   0  42   5   8

Как видно из приведенного выше результата, числа 5, 0 и 23 и т. Д. Были повторены. Я на самом деле хочу полностью исключить 0 с и не повторять ни одного числа. Приведенный ниже ожидаемый результат демонстрирует желаемый результат.

 2  20  12  15  9
19  10  42  13  3
 7  38  50   1 33
 6  22  49   4 21
48   8  25  11  3

Выше не имеет 0 и никакие числа не повторяются.

Вот мой текущий сценарий.

use strict;
use warnings;

for (1..5) {
my @numbers;
my %unique;

for (1..5) {
    my $number = int rand(50);
    redo if $unique{$number}++;
    push @numbers, $number;
 }
 print join('  ', @numbers), "\n";
}

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

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Нет необходимости продолжать тестирование на уникальность: обычный способ выбрать несколько случайных неповторяющихся подмножеств из списка значений - это shuffle этот список первым. Затем подмножества могут быть взяты из списка без замены для достижения желаемого результата

use strict;
use warnings 'all';

use List::Util 'shuffle';

my @list = shuffle 1 .. 50;

print join("\t", splice @list, 0, 5), "\n" for 1 .. 5;

выход

36  18  14  32  22
6   38  1   19  33
27  9   45  34  12
26  49  10  43  37
28  8   21  39  11
0 голосов
/ 30 апреля 2018

Переместите объявление %unique за пределы первого цикла, и оно будет работать.

#!/usr/bin/env perl

use strict;
use warnings;
my %unique;
for ( 1 .. 5 ) {
   my @numbers;

   for ( 1 .. 5 ) {
      my $number = int rand(49) + 1;
      redo if $unique{$number}++;
      push @numbers, $number;
   }
   print join( "\t", @numbers ), "\n";
}

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

Ваша другая проблема - вы, кажется, не хотите 0 в миксе - так что вам просто нужно добавить 1 ко всему.

Вы также можете использовать функцию List::Util s shuffle:

#!/usr/bin/env perl

use strict;
use warnings;

use List::Util qw ( shuffle );

my @pick_list = shuffle( 1 .. 50 );

for ( 1 .. 5 ) {
   print join "\t", splice( @pick_list, 0, 5 ), "\n";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...