为三个元素数组创建乘积矩阵。我知道Perl没有多维数组,并且被展平了。我一直在使用refs,但是我似乎无法克服for循环问题,即将三个产品放入一个数组中并将该数组推入另一个数组中。而且我也可以离开。很好,但是我花了很多时间。
我已经将值移入和移出了不同的位置,即{},打印出变量,直到我变成蓝色,并全部使用$ last进行调试。我现在可能会炸。
use strict;
use warnings;
my @array1 = (1, 2, 3);
my @array2 = (2, 4, 6);
my @matrixArray = ();
my $matrixArray;
my @row;
my @finalArray = maths(\@array1, \@array2);
print @finalArray;
sub maths{
my $array1ref = shift;
my $array2ref = shift;
my $value1;
my $value2;
my $maths;
my @row = ();
my @array1 = @{$array1ref};
my @array2 = @{$array2ref};
my $len1 = @array1;
my $len2 = @array2;
for my $x (0 ..($len1 -1)){
#iterate through first array at each value
$value1 = $array1[$x];
#print $value1, " value1 \n";
for my $y (0 .. ($len2 -1)){
#iterate through second array at each value
$value2 = $array2[$y];
#print $value2, " value2 \n";
#calculate new values
$maths = $value1 * $value2;
#exactly right here
#print $maths, " maths \n" ;
push @row, $maths;
}
}
#and exactly right here but not set of arrays
#print @row, "\n";
return @row;
}
目前我能得到这个:246481261218。这是正确的愚蠢数学,但是...
它应该显示为矩阵:
2 4 6 4 8 12 6 12 18
我没有传递三个数组,所以看来我的问题出在子例程上,然后我才能继续进行其他工作。这似乎是我经常想念的主题。非常抱歉,我听起来很无能。
编辑*** 可以,但是我无法打开包装
use strict;
use warnings;
my @array1 = (1, 2, 3);
my @array2 = (2, 4, 6);
my @matrixArray = ();
maths(\@array1, \@array2);
foreach my $x (@matrixArray){
print "$x \n";
}
sub maths{
my $array1ref = shift;
my $array2ref = shift;
my $value1;
my $value2;
my $maths;
my @row = ();
my $row;
my @array1 = @{$array1ref};
my @array2 = @{$array2ref};
my $len1 = @array1;
my $len2 = @array2;
for my $x (0 ..($len1 -1)){
#iterate through first array at each value
$value1 = $array1[$x];
for my $y (0 .. ($len2 -1)){
#iterate through second array at each value
$value2 = $array2[$y];
#calculate new values
$maths = $value1 * $value2;
push @row, $maths;
$row = \@row;
}
push @matrixArray, $row;
}
return @matrixArray;
}
函数调用后的输出为:
ARRAY(0x55bbe2c667b0) ARRAY(0x55bbe2c667b0) ARRAY(0x55bbe2c667b0)
这是$ x的(第10行)打印内容。
****编辑 这有效(几乎):
print join(" ", @{$_}), "\n" for @matrixArray;
输出有点错误...
2 4 6 4 8 12 6 12 18
2 4 6 4 8 12 6 12 18
2 4 6 4 8 12 6 12 18
值得注意的是:我知道$ x是一个数组,但是尝试正确解压缩它似乎遇到麻烦。而且我不再是Perl的粉丝。我正在寻找Python的峡湾。
和*****编辑 这很好用,我得到了三个数组:
sub maths{
my ($array1, $array2) = @_;
my @res;
for my $x (@$array1) {
my @row;
for my $y (@$array2) {
push @row, $x * $y;
}
push @res, \@row;
}
#This is the correct structure on print @res!
return @res;
}
但是,尽管它正确地组合在一起,但通话后我没有输出
maths(\@array1, \@array2);
这里什么都没有...
print @res;
print join(" ", @{$_}), "\n" for @res;
foreach my $x (@res){
print join(" ", @{$x}), "\n";
}
当然要感谢一百万!我后悔参加了这门愚蠢的课程,并担心我的成绩最终会帮助我。仍然希望使用Python!
答案 0 :(得分:4)
看来,您需要一个矩阵,其中的行是通过将一个数组乘以另一个元素而获得的。
一种方式
use warnings;
use strict;
use Data::Dump qw(dd);
my @ary = (2, 4, 6);
my @factors = (1, 2, 3);
my @matrix = map {
my $factor = $_;
[ map { $_ * $factor } @ary ]
} @factors;
dd @matrix;
由外部@matrix
形成的数组map
具有每个元素的数组引用,因此(至少)是二维结构(“矩阵”)。这些arrayrefs是用[ ]
构建的,它从内部的列表中创建了一个匿名数组。该列表由map
在@ary
上方生成。
我使用Data::Dump很好地打印复杂数据。核心是Data::Dumper
。
在进行大量此类工作以及处理大量数据时,效率可能很重要。众所周知,直接迭代应该比map
快一点,但这是一个基准。这也有助于展示更多基本方法。
use warnings;
use strict;
use feature 'say';
use Benchmark qw(cmpthese);
my $runfor = shift // 5; # run each case for these many seconds
sub outer_map {
my ($ary, $fact) = @_;
my @matrix = map {
my $factor = $_;
[ map { $_ * $factor } @$ary ]
} @$fact;
return \@matrix;
}
sub outer {
my ($ary, $fact) = @_;
my @matrix;
foreach my $factor (@$fact) {
push @matrix, [];
foreach my $elem (@$ary) {
push @{$matrix[-1]}, $elem * $factor;
}
}
return \@matrix;
}
sub outer_tmp {
my ($ary, $fact) = @_;
my @matrix;
foreach my $factor (@$fact) {
my @tmp;
foreach my $elem (@$ary) {
push @tmp, $elem * $factor;
}
push @matrix, \@tmp;
}
return \@matrix;
}
my @a1 = map { 2*$_ } 1..1_000; # worth comparing only for large data
my @f1 = 1..1_000;
cmpthese( -$runfor, {
direct => sub { my $r1 = outer(\@a1, \@f1) },
w_tmp => sub { my $r2 = outer_tmp(\@a1, \@f1) },
w_map => sub { my $r3 = outer_map(\@a1, \@f1) },
});
在具有v5.16的漂亮机器上,此打印结果
Rate direct w_map w_tmp direct 11.0/s -- -3% -20% w_map 11.4/s 3% -- -17% w_tmp 13.8/s 25% 21% --
在v5.29.2和老式笔记本电脑上,结果非常相似。
因此,map
比直接构建矩阵要快,比使用临时行数组的方法要慢15-20%,我也认为这是最清晰的。通过避免范围和标量,可以显式改善循环,并且可以通过使用索引来加速“直接”方法。但是这些都是可怕的微观优化,最多只能带来附带的好处。
请注意,此类计时仅对于真正大量的数据才有意义,而上述情况则没有。 (我确实对这两个尺寸进行了十倍大的测试,结果非常相似。)
答案 1 :(得分:2)
第二个程序大部分是正确的。
问题在于您没有解压缩数组的第二层。
foreach my $x (@matrixArray){
print "$x \n";
}
应该是这样的:
foreach my $x (@matrixArray) {
print join(" ", @{$x}), "\n";
}
# or just:
print join(" ", @{$_}), "\n" for @matrixArray;
通过删除不必要的临时变量和索引,可以使您的maths
函数更短而不失去可读性(实际上可能会使它更清晰)。例如:
sub maths {
my @array1 = @{ $_[0] };
my @array2 = @{ $_[1] }; # or: ... = @{ (shift) };
my @res = ();
for my $x (@array1) {
my @row = (); # <-- bugfix of original code
for my $y (@array2) {
my $maths = $x * $y;
push @row, $maths;
}
push @res, \@row;
}
return @res;
}