2012-02-27 116 views
1

所以我得到的输入从标准输入,如:如何在perl中从STDIN创建多个多维数组?

1 2 3 
4 5 6 
7 6 3 

4 3 2 
2 3 5 
2 5 1 

空白行分开的矩阵,因此上述输入要创建两个多维数组...我知道了如何创建一个(下面的代码),但是如何根据用户输入的空行数量创建多个?

我不知道用户想要创建多少个数组,因此如何根据用户输入中的空行动态创建数组?

my @arrayrefs; 


while(<>) 
{ 

chomp; 

    my @data = split(/\s+/,$_); 
    push @arrayrefs, \@data; 
} 


for $ref (@arrayrefs){ 
    print "[@$ref] \n"; 
} 

回答

1

与您的数据,我想说输入流使用段落模式将是一个好主意。这基本上将input record separator $/设置为"\n\n",但在这种情况下,我们将使用“”,这更具神奇性,因为它具有额外的空行灵活性。

use strict; 
use warnings; 
use Data::Dumper; 

sub parse_data { 
    my @matrix = map { [ split// ] } split /\n/, shift; 
    return \@matrix; 
} 

my @array; 
$/ = ""; 
while (<>) { 
    push @array, parse_data($_); 
} 
print Dumper \@array; 

map/split语句不像看起来那么复杂。从右读向左:

  • shift从参数列表@_
  • split上换行符这样的说法
  • 采取每个那些(即map他们)分论点,并再次split他们对空间的说法,并把结果在一个匿名数组内,使用括号[ ]

全部完成。

+0

或者:'my @array = map {parse_data($ _)} <>;' – Zaid 2012-02-27 12:58:25

+0

@Zaid也可以。 – TLP 2012-02-27 13:03:43

+0

+1。你可以将'parse_data'的主体改为'[map {[split//]} split/\ n /,shift]'而不会丢失可读性。 – flesk 2012-02-27 13:27:07

0

它不会赢得任何代码高尔夫比赛,但它似乎工作:

$ cat data 
1 2 3 
4 5 6 
7 6 3 

4 3 2 
2 3 5 
2 5 1 
$ cat xx.pl 
#!/usr/bin/env perl 
use strict; 
use warnings; 

my @matrices; 
my @matrix; 

sub print_matrices() 
{ 
    print "Matrix dump\n"; 
    foreach my $mref (@matrices) 
    { 
     foreach my $rref (@{$mref}) 
     { 
      foreach my $num (@{$rref}) 
      { 
       print " $num"; 
      } 
      print "\n"; 
     } 
     print "\n"; 
    } 
} 

while(<>) 
{ 
    chomp; 
    if ($_ eq "") 
    { 
     my(@result) = @matrix; 
     push @matrices, \@result; 
     @matrix =(); 
    } 
    else 
    { 
     my @row = split(/\s+/,$_); 
     push @matrix, \@row; 
    } 
} 

# In case the last line of the file is not a blank line 
if (scalar(@matrix) != 0) 
{ 
     my(@result) = @matrix; 
     push @matrices, \@result; 
     @matrix =(); 
} 

print_matrices(); 
$ perl xx.pl data 
Matrix dump 
1 2 3 
4 5 6 
7 6 3 

4 3 2 
2 3 5 
2 5 1 

$ 
0
#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 

my @arrays = []; 

while (<>) { 
    if (my @array = /(\d+)/g) { 
     push $arrays[$#arrays], \@array; 
    } else { 
     push @arrays, []; 
    } 
} 

$Data::Dumper::Indent = 0; 
printf("%s\n", Dumper $arrays[0]); 
printf("%s\n", Dumper $arrays[1]); 

输出:

$VAR1 = [['1','2','3'],['4','5','6'],['7','6','3']]; 
$VAR1 = [['4','3','2'],['2','3','5'],['2','5','1']];