在 perl 中,如何生成文件中包含的所有可能的数字组合?

In perl how can I generate all possible combinations of numbers contained in a file?

我在本地找到了以下 perl 代码,它计算字符或数字的所有可能组合,但你需要使用 qw 函数提供它们 my @strings = [qw(1 2 3 4 5 6 7 8 9 10 11 12 13)];,我需要读取这些数字 (1 2 3 4 5 6 7 8 9 10 11 12 13) 从文件并将它们传递给 @strings 数组或通过 Perl 行命令参数将数字传递给提到的 @strings 数组。

我已经阅读了所有关于 qw() 的信息,但是在阅读 Perl 行命令参数文件时我没有找到使用它的方法,所以你能提供一些建议来解决这个问题吗.

现在提供的输出是:

1 2 3 4 5
1 2 3 4 6
1 2 3 4 7 ...

代码:

use strict;
use warnings;

#my $strings = [qw(AAA BBB CCC DDD EEE)];
#my $strings = [qw(1 2 3 4 5 6 7 8 9 10 11 12 13)];
my @strings = [qw(1 2 3 4 5 6 7 8 9 10 11 12 13)];

sub combine;

print "@$_\n" for combine @strings, 5;

sub combine {

  my ($list, $n) = @_;
  die "Insufficient list members" if $n > @$list;

  return map [$_], @$list if $n <= 1;

  my @comb;

  for (my $i = 0; $i+$n <= @$list; ++$i) {
    my $val  = $list->[$i];
    my @rest = @$list[$i+1..$#$list];
    push @comb, [$val, @$_] for combine \@rest, $n-1;
  }

  return @comb;
}

这段代码从文件中初始化一个数字数组 (@numbers):

use strict;
use warnings;

my $filename = "data.txt";
my @numbers; 

open my $fh, "<", $filename or die "Cannot open $filename";

# Read each line into $line
while( my $line = <$fh> ) {
    # Extract each number present at $line
    while( $line =~ /(\d+)/g ) {
        # If found, add the number to @numbers
        push @numbers, ;
    }
}

close $fh;

"data.txt" 内容可能是这样的:

1 2 3
4
5
6 7 8
9
10 11
12

每一行中是否有多个数字都没关系。如果事实上它们可以在一行中带有分隔符(不是数字的东西,比如白色 space)

首先,这是不对的:

my @strings = [qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 )];

这将创建一个包含单个元素的数组,该元素是对另一个数组的引用。

你想要

my @strings = qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 );
combine \@strings, 5;

my $strings = [qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 )];
combine $strings, 5;

qw(...) 等同于 split ' ', q(...),其中 q(...) 只是 '...' 具有不同的分隔符。

这意味着

my @strings = qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 );
combine \@strings, 5;

等同于

my @strings = split(' ', ' 1 2 3 4 5 6 7 8 9 10 11 12 13 ');
combine \@strings, 5;

当然,我们不需要使用single-quotes来构造我们传递给split的字符串;我们可以使用传递一个从读取文件创建的字符串。

因此,reading-from-file 相当于

my @strings = qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 );
combine \@strings, 5;

会是

my $line = <>;
chomp($line);
my @strings = split(' ', $line);
combine \@strings, 5;

chomp 实际上不是必需的,因为 split ' ' 会忽略尾随空格。)

您可以使用 Algorithm::Combinatorics:

来做同样的事情
use Algorithm::Combinatorics qw(combinations);
my @data = qw(1 2 3 4 5 6);
say join " ", @$_ for combinations( \@data, 2);

输出:

1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6