2012-02-27 96 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']];