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

时间:2020-10-10 06:53:05

标签: file perl combinations args

我在本地找到了以下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;
}

3 个答案:

答案 0 :(得分:3)

这段代码初始化了文件中的数字数组(@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, $1;
    }
}

close $fh;

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

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

每行中是否有多个数字都没关系。如果可以的话,它们可以放在一行中并带有分隔符(数字以外的东西,例如空格)

答案 1 :(得分:3)

首先,这是不对的:

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;

但是,当然,我们不需要使用单引号来构造传递给split的字符串;我们可以使用传递通过读取文件而创建的字符串。

所以,从文件读取等同于

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 ' '会忽略尾随空白。)

答案 2 :(得分:2)

您可以使用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
相关问题