繁体   English   中英

如何从Perl中的标准输入构建2D矩阵?

[英]How can I build a 2D matrix from standard input in Perl?

好的,这整个周末我一直在苦苦挣扎,我得到了很多帮助,但我仍然没有得到帮助。 到目前为止,这是我的代码:我要做的是根据用户输入构建一些矩阵。 最终我想乘以它们。 另一个故事。

输入如下

1 2 2 4
4 5 6 6

1 2 2 3
1 2 2 3

sub makeMatrix {
  my ($input) = @_;
  my @mat;
  while (<$input>) {
    if ($input eq ""){
        print "it's blank\n";
        return;
    }
    else{
        push @mat, [ split ];
    }
    return \@mat;
    }
}

my @a = ();
while($a = <>) {
    chomp $a;
    push @a,($a);
    }


@matrices;
push @mat, (makeMatrix(@a));

foreach $input (@matrices){
    print "input was $input\n";

}

为什么不起作用? 为什么不在@matrices创建矩阵数组? 它是子例程中的return语句吗? 我的目标是在矩阵数组中有两个矩阵。 感谢你的帮助。

您似乎对<>运算符的含义有些困惑。

线

while (<$input>)

是错的。 这告诉Perl从文件句柄$input读取。 但是,传递给子例程的不是文件句柄,而是一段文本。 您在这里不需要<>。 另外,您似乎已经舍弃了该子例程的大部分输入。 您这样称呼它:

makeMatrix(@a)

但是您只能在例程中使用@a的第一个值。 该例程应如下所示:

use warnings;
use strict;

sub makeMatrix {
    my @inputs = @_;
    my @mat;
    for my $input (@inputs) {
        # print "$input\n"; # debugging code left here for artistic effect
        if ($input eq "") {
            print "it's blank\n";
        }
        else{
            push @mat, [ split /\s+/, $input ];
        }
    }
    return \@mat;
}

my @a;

while ($a = <>) {
    chomp $a;
    push @a, $a;
}


my $matrices = makeMatrix (@a);

for my $row (@$matrices){
    for my $column (@$row) {
        print "input was $column\n";
    }
}

您向makeMatrix传递makeMatrix一个字符串数组,但该函数假装将其传递给文件句柄。

我不知道你为什么要经历这么多的麻烦,但这是代码的大问题。

另外, 如果将真实的文件句柄传递给makeMatrix ,则该行

while (<$input>) {
   if ($input eq ""){

不会做您认为应该做的事。

while (<$input>) {

将在每次迭代中将行读入$_ 所以:

   if ($input eq ""){

将始终为false,因为$input将是一个文件句柄(因此不等于空字符串)。 此外,即使您已正确编写

   if ($_ eq ""){

因为你没有条件会在遇到一个空行假chomp掉结束线( $_不会是空的)。

总而言之,这真是一堆乱七八糟的代码,读者只能尝试猜测您要尝试执行的操作。 考虑一下您想要完成的工作,并对其进行更好的解释。

http://learn.perl.org/具有大量学习Perl的资源。

下面的代码非常晦涩,我不建议在生产中使用它,但是尝试弄清楚它可能会教给您很多知识:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

while ( my $matrix = read_matrix() ) {
    print Dumper $matrix;
}

sub read_matrix {
    local $/ = "\n\n";
    return if eof DATA;
    return [ map { [ split ] } split /\n/, scalar <DATA> ];
}

__DATA__
1 2 2 4
4 5 6 6

1 2 2 3
1 2 2 3

输出:

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

马特,请检查我在下面写的内容,以了解我是否已理解该问题:

我的一般观点是:

(1)您的示例数据不适用于矩阵乘法。 如果您的第一个数组是2x4,那么您的第二个数组必须是4x2,答案是2x2。

(2)Perl为您提供了一种非常强大的数据语言(PDL),可以有效地处理矩阵。 如果您要进行很多矩阵代数运算,我建议您使用它。

(3)如果您先将数据读取到2D数组(AoA是数组数组)中,则矩阵乘积下方的解决方案会分3行显示。

#!/usr/bin/perl
use strict;
use warnings;
use PDL; # perl data language enables matrix multiplication
use Inline::Files; #multiple virtual files inside code

my @AoA_A = make_matrix("ARRAY_A"); #read in 2D array
my @AoA_B = make_matrix("ARRAY_B");

my $a = pdl [ @AoA_A ]; #Construct new pdl object
my $b = pdl [ @AoA_B ];
my $c = $a x $b;  # x overload
print "matrix a", $a;
print "matrix b", $b;
print "matrix c",$c;

sub make_matrix {
    my $source = shift;
    my @AoA;
    while (<$source>){
        my @tmp = split;
        push @AoA, [ @tmp ];
    }
    return @AoA;  
}

__ARRAY_A__
1 2 2 4
4 5 6 6
__ARRAY_B__
1 2
2 3
1 2
2 3

它创建了以下输出:

matrix a
[
 [1 2 2 4]
 [4 5 6 6]
]
matrix b
[
 [1 2]
 [2 3]
 [1 2]
 [2 3]
]
matrix c
[
 [15 24]
 [32 53]
]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM