我有以下代码
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++;
}
但是,我认为这可能会给我带来同样的问题,因为可能会有重复。
有没有更快的方法来保持我的阵列中的四个数字都是唯一的?
答案 0 :(得分:2)
要生成四个唯一非零小数位的列表,请使用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;
答案 1 :(得分:0)
@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;