如何在Perl中创建一个完全唯一的数字集

时间:2018-04-30 07:55:46

标签: perl

我正在尝试编写一个perl脚本,用于创建一组完整的唯一随机数。

假设我有150的数字我想创建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

如上述结果所示,重复了5023等数字。我实际上想要完全排除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 :(得分:6)

%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";
}

答案 1 :(得分:1)

无需继续测试唯一性:从值列表中选择多个随机非重复子集的常用方法是首先列出的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