如何在Perl中创建二维数组?

时间:2010-10-14 13:17:38

标签: arrays perl file matrix multidimensional-array

我目前正在尝试将32 x 48的矩阵文件传递给Perl中的多维数组。我能够访问所有值,但访问特定值时遇到问题。任何帮助将不胜感激。我已经设置了数据集的链接以及我下面的代码。

以下是数据集的链接: http://paste-it.net/public/x1d5301/

这就是我现在的代码。

#!/usr/bin/perl

open FILE, "testset.txt" or die $!;
my @lines = <FILE>;

my $size = scalar @lines;

my @matrix = (1 .. 32);
my $i = 0;
my $j = 0;
my @micro;

foreach ($matrix)
{

foreach ($lines)
{
    push @{ $micro[$matrix]}, $lines;
}
}

5 个答案:

答案 0 :(得分:7)

似乎您不理解$matrix仅在@matrix后面紧跟一个数组索引器[ $slot ]时才表示$matrix。否则,@matrix是与%matrix完全不同的变量(两者都与#!/usr/bin/perl use English; 不同)。请参阅perldata

$MATCH

不要!使用英语 - 那样

这会带来$PREMATCH$POSTMATCH$&并导致可怕的$',$`,open FILE, "testset.txt" or die $!; 惩罚。你应该等到使用一个英文变量,然后再导入它。

my @lines = <FILE>;

两件事:1)使用lexical file handles,2)使用三个{arg open

my $size = scalar @lines;

my @matrix = (1 .. 32);
my $i = 0;
my $j = 0;
my @micro;

只要我选择:不要啜饮大文件。 (这不是这种情况,但这是一个很好的警告。)

foreach ($matrix) {

我看到我们在"PROFIT!!"阶段......

$matrix

您没有变量@matrix,您有变量 foreach ($lines) {

$lines

push @{ $micro[$matrix]}, $lines; } } 也是如此。

use strict;
use warnings;
use English qw<$OS_ERROR>; # $!
open( my $input, '<', 'testset.txt' ) or die $OS_ERROR;

# I'm going to assume space-delimited, since you don't show
my @matrix;
# while ( defined( $_ = <$input> ))...
while ( <$input> ) {
    chomp; # strip off the record separator
    # load each slot of @matrix with a reference to an array filled with
    # the line split by spaces.
    push @matrix, [ split ]; # split = split( ' ', $_ )
}

重写:

{{1}}

答案 1 :(得分:3)

如果您打算做一些数学运算,可以考虑使用PDL(Perl数据语言)。您可以在操作之前轻松设置矩阵:

use 5.010;

use PDL;
use PDL::Matrix;

my @rows;
while( <DATA> ) {
    chomp;
    my @row = split /\s+/;
    push @rows, \@row;
    }

my $a = PDL::Matrix->pdl( \@rows );
say "Start ", $a;

$a->index2d( 1, 2 ) .= 999;
say "(1,2) to 999 ", $a;

$a++;
say "Increment all ", $a;

__DATA__
1 2 3
4 5 6
7 8 9
2 3 4

输出显示矩阵演变:

Start 
[
 [1 2 3]
 [4 5 6]
 [7 8 9]
 [2 3 4]
]

(1,2) to 999 
[
 [  1   2   3]
 [  4   5 999]
 [  7   8   9]
 [  2   3   4]
]

Increment all 
[
 [   2    3    4]
 [   5    6 1000]
 [   8    9   10]
 [   3    4    5]
]

在矩阵的每个成员上运行任意和复杂的操作都有相当大的力量,就像我向每个成员添加1一样。你完全跳过循环杂技。

不仅如此,PDL还有很多特殊的东西可以使数学运算速度非常快并且占用内存很少。您想要做的一些事情可能已经实施。

答案 2 :(得分:2)

您可能需要chomp值:

chomp( my @lines = <FILE> );

答案 3 :(得分:1)

我正在制作这个CW,因为它的唯一目的是澄清我在@Axeman's answer的评论中提出的切入点。见perldoc -f split

  

/\s+/上的拆分类似于split(' '),但任何前导空格都会产生空的第一个字段。没有参数的拆分确实在内部split(' ', $_)

#!/usr/bin/perl

use YAML;

$_ = "\t1 2\n3\f4\r5\n";

print Dump { 'split'       => [ split       ] },
           { "split ' '"   => [ split ' '   ] },
           { 'split /\s+/' => [ split /\s+/ ] }
           ;

输出:

---
split:
  - 1
  - 2
  - 3
  - 4
  - 5
---
split ' ':
  - 1
  - 2
  - 3
  - 4
  - 5
---
split /\s+/:
  - ''
  - 1
  - 2
  - 3
  - 4
  - 5

答案 4 :(得分:1)

我看到这个问题很老了,但是正如作者刚刚编辑过这个问题,也许这仍然是有趣的。此外,数据的链接已经死亡,但由于其他答案使用空格作为分隔符,我也会这样做。

此答案演示了Tie::Array::CSV,它允许随机访问CSV(或使用Text::CSV可解析的其他文件)。

#!/usr/bin/env perl

use strict;
use warnings;

use Tie::Array::CSV;

## put DATA into temporary file
## if not using DATA, put file name in $file
use File::Temp ();
my $file = File::Temp->new();
print $file <DATA>;
##


tie my @data, 'Tie::Array::CSV', $file, { 
  text_csv => {
    sep_char => " ",
  },
};

print $data[1][2];

__DATA__
1 2 3 4 5
6 7 8 9 1
2 3 4 5 6