如何在 Perl 中打印多维数组?

How can I print a multidimensional array in Perl?

我试图在 Perl 中打印一个多维数组(矩阵),将对数组的引用传递给子例程。

这是我的代码:

sub print_matrix(\@) {
      my $array = shift;
      for my $i ( 0 .. $#{ $array } ) {
        my $row = $array[$i];
        for my $j ( 0 .. $#($row) ) {
         print $array[$i][$j];
        }
      }
}

你可以用类似这样的东西非常简单地打印一个二维 Perl 数组

use strict;
use warnings;

my @arr_2d = (
    [ qw/ a b c d / ],
    [ qw/ e f g h / ],
    [ qw/ i j k l / ],
);

print_2d(\@arr_2d);

sub print_2d {
    my ($matrix) = @_;
    print "@$_\n" for @$matrix;
}

输出

a b c d
e f g h
i j k l

更新

这是您自己的代码的工作版本。您没有正确使用数组引用,并且在应该有大括号的地方有括号。此版本还在每个元素后打印一个 space 并在每行后打印一个换行符。

sub print_matrix {
  my $array = shift;
  for my $i ( 0 .. $#{ $array } ) {
    my $row = $array->[$i];
    for my $j ( 0 .. $#{ $row } ) {
      print $array->[$i][$j], ' ';
    }
    print "\n";
  }
}

Borodin 告诉您您的代码出了什么问题。

现在考虑这个模块:Data::Dumper(在 CPAN 上可用)。您可以使用此模块打印任何数据结构:arrayrefs 的 arrayref(您所谓的矩阵)、hashrefs 的 hashref、hashrefs 的 arrayref、hashrefs 的 hashref 或这些结构的任何其他组合,用于任意多维。当然,如果维度太多,可能会导致输出混乱。

我的意思是,前段时间,我在面试中被问到我将如何实现这个模块。我认为这是一个非常聪明的问题。我不得不考虑一下,因为我经常使用该模块,但从来没有想过它是如何工作的。其实很简单。想象一下,在您的子例程中您收到了一个引用,但您实际上并不知道它是什么类型的引用(scalarref、arrayref、hashref 等),您将如何确定它是什么?如果你有多种可能性,你会怎么做才能涵盖所有这些可能性?您是否考虑过创建递归函数?

因此,为了快速解决您的问题,如果您只是为了调试目的而打印矩阵,请使用 Data::Dumper。否则,如果您想做一些更复杂的事情并希望涵盖多种情况,请尝试创建一个递归函数。

这是一个 Data::Dumper 示例:

my $arrayref = [
    [ qw/ a b c d / ],
    [ qw/ e f g h / ],
    [ qw/ i j k l / ],
];

use Data::Dumper;

print Dumper $arrayref;

这是您将得到的结果:

$VAR1 = [
          [
            'a',
            'b',
            'c',
            'd'
          ],
          [
            'e',
            'f',
            'g',
            'h'
          ],
          [
            'i',
            'j',
            'k',
            'l'
          ]
        ];

矩阵的每个 "row" 都打印为元素列表,由一对括号内的逗号(和换行符)分隔。小心,如果你给它传递一个数组,它会一个一个地打印每个元素,你会丢失 "dimensions"。如果你只有一个数组,你必须像这样将它作为引用传递:

print Dumper \@array;

希望对您有所帮助。

当你的矩阵中只有单个字母条目时,使用普通 print 是可以的,但是像 Text::Table 这样的模块可以更容易地产生整洁的输出。例如,

#!/usr/bin/env perl

use strict;
use warnings;

use Text::Table;

my @matrix = map {
    [ map sprintf('%.2f', -500 + rand(1000)), 1 .. 5 ]
} 1 .. 5;

my $mat = Text::Table->new;
$mat->load(@matrix);

print $mat;

输出:

  -7.73  -83.85 -351.18   21.06  320.40
 174.83  238.29   91.16  361.43  213.04
 446.43   -4.82  322.81   10.38 -436.62
-128.05  195.68  199.05  288.39  115.30
-251.19 -329.35  244.13 -428.25  454.64