Perl的新手,我正在尝试定义一个字符子集,然后在文本文件中输出它们的所有可能组合(最多8个字符)。
我真的不喜欢'默认变量'或Perl的其他方面,所以我开始使用伪代码,希望有人可以帮我详细说明(我从例子中学到的最好)。
#Define output file
$filename=output.dat
$standard_output->$filename
#Define list
$list[]=regex/a..z 0..9/
#Cycle through iterations
foreach $letter1 in $list{
print $list[$letter]
}
foreach $letter1 in $list{
foreach $letter2 in $list{
print $list[$letter1] $list[$letter2]
}
}
...
foreach letter1 in list{
foreach letter2 in list{
foreach letter3 in list{
foreach letter4 in list{
foreach letter5 in list{
foreach letter6 in list{
foreach letter7 in list{
foreach letter8 in list{
print list[letter1] list[letter2] list[letter3] list[letter4] list[letter5] list[letter6] list[letter7] list[letter8]
}
}
}
}
}
}
}
}
你可以清楚地看到,我对此非常陌生。有人可以帮我解决Perl问题吗?
答案 0 :(得分:4)
我的Set::CrossProduct模块使这很简单,并且没有堆栈或内存破坏递归就可以实现:
use v5.10;
use Set::CrossProduct;
my $min = 2;
my $max = 4;
my $set = [ qw( a b 1 2 ) ];
foreach my $length ( $min .. $max ) {
say "Getting combinations of length $length";
my $cross = Set::CrossProduct->new(
[ ( $set ) x $length ]
);
while( my $tuple = $cross->get ) {
say join '', @$tuple;
}
}
答案 1 :(得分:3)
功能编程*拯救!以下代码效率不高,但更清晰。
我们将定义一个以数字和列表作为参数的函数。数字表示我们要递归的次数,该列表包含来自外层的字母。
#!/usr/bin/perl
use strict; use warnings;
my @list = 'a' .. 'z'; # lowercase letters
sub combinations {
my ($recursions, @letters) = @_; # unpack the arguments
if ($recursions == 0) {
print @letters, "\n"; # print the letters, append newline
} else {
# do a loop
$recursions--; # reduce level
for my $letter (@list) {
combinations($recursions, @letters, $letter);
}
}
}
我们可以使用combinations(8);
调用该子以获得预期结果。
..
是范围运算符并生成一个列表。它也适用于字母字符。您需要'a' .. 'z', 0 .. 9
。
虽然您可能希望使用较小的@list
进行测试,但它仍然有效。
这会生成所有固定长度的字符串。要使所有字符串达到给定长度,只需执行
combinations($length) foreach my $length (1 .. 8);
(广度优先),或包括
print @list, "\n";
在for
- 循环之前的else
- 分支中,深度优先。
脚注:
(*)不,不是真的,但这很接近。功能编程根本不需要任何循环。