创建一系列唯一的随机数字

Creating a sequence of unique random digits

我有以下代码

use strict;
use warnings;
use 5.22.0;

# Generating random seed using 
# Programming Perl p. 955
srand( time() ^ ($$ + ($$ << 15 ) ) );

# Generating code that could have duplicates
my @code = (
    (int(rand(9)) + 1),
    (int(rand(9)) + 1),
    (int(rand(9)) + 1),
    (int(rand(9)) + 1)
);

# Trying to remove duplicates and choosing the unique code
my %seen = ();
my @unique = grep { ! $seen{ $_ }++ } @code;
say @unique;

我正在生成一个包含四个随机数的列表,我需要确保所有四个数字都是唯一的。我能够刮出唯一数字,但它并不总是保持 4 的标量长度。

我最初的想法是进行 foreach 循环检查以查看每个元素是否相同,但必须有一种更快的方法来执行此操作。

这是我的初步想法(不使用唯一集)

my $index = 0
foreach my $element (@code) {
    if ($element == $code[index]) {  
        # repopulate @code at said element
        $code[$index] = (int(rand(9)) + 1);
    }
    $index++;
 }

但是,我认为这可能会给我同样的问题,因为可能存在重复。

有没有更快的方法来做到这一点,同时在我的数组中保持四个唯一的数字?

要生成四个唯一的非零十进制数字的列表,请使用 List::Util 中的 shuffle 并选择前四个

像这样

use strict;
use warnings;
use 5.010;

use List::Util 'shuffle';

my @unique = (shuffle 1 .. 9)[0..3];

say "@unique";

输出

8 5 1 4

不需要像 Perl 那样为随机数生成器设置种子。只有在需要 可重复 随机序列

时才使用 srand

更新

这是与您已有的方法类似的另一种方法。本质上它只是不断生成随机数,直到它有四个不同的

use strict;
use warnings;
use 5.010;

my %unique;
++$unique{int(rand 9) + 1} while keys %unique < 4;

say join ' ', keys %unique;

@Boromir 给了你可能是最干净的解决方案。如果您确实需要使用 rand(),只需首先确保不保存重复项,而不是稍后删除它们:

#!/usr/bin/perl
use strict;
use warnings;
use 5.22.0;
# Generating random seed using 
# Programming Perl p. 955
srand(time()^($$+($$<<15)));

#Generating code that can't have duplicates
my %seen = ();
while (scalar(keys(%seen)!=4)) {
    $seen{int(rand(9)) + 1}++
}
say keys %seen;