如何解决Perl:如何向多维数组中的每一行添加额外的列
我有两个多维数组:array1(@wipr) 和 array2(@widesc)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
# Initializing and defining the array
my @wipr = ( ['1111','2221'],['1112','2222'],['1113','2223'],['1115','2225'],'2224'] );
my @widesc = ( ['1111','Bug1'],'Feature1'],'Feature2'],['1114','Feature2'] );
# Printing items from the array
#print Dumper(\@wipr);
#print Dumper(\@widesc);
# Using For loop
for(my $m = 0; $m <= $#wipr; $m++)
{
for(my $n = 0; $n <= $#widesc ; $n++)
{
#print $wipr[$m][0],"\n";
#print $widesc[$n][0];
if ( "$wipr[$m][0]" == "$widesc[$n][0]" )
{
print "Matches: $wipr[$m][0] == $widesc[$n][0]";
my $desc="$widesc[$n][1]";
print "desc value is : $desc";
#push(@{$wipr[$m][1][$m]},"$desc");
#print "$wipr[$m][1][$m]";
$wipr[$m][1][$m] = "'$desc'";
#push (@wipr,$wipr[$m][1][$m]);
}
#else
#{
# print "Doesn't Matches: $wipr[$m][0] == $widesc[$n][0]";
#}
}
print "\n";
}
print Dumper(\@wipr);
如果array1(@wipr)中第一列的值与array2(@widesc)中第一列的值匹配,我们需要将array2的第二个元素添加到array1中。 如果值不匹配,它应该只输入一个字符串“未找到”
所需的输出应该是:
my @result= ( ['1111','2221','2222','2223','2225','Not Found'],'2224','Feature2'] );
我在 array1 中添加第三列时遇到了困难。你能帮忙吗。
错误:不能使用字符串(“2221”)作为数组引用,而在 arrays1.pl line33 中使用“strict refs”。
解决方法
天真的方法:
my @result;
for my $wipr (@wiprs)
my $wi1 = $wipr->[0];
for my $widesc (@widescs)
my $wi2 = $widesc->[0];
if ($wi1 == $wi2) {
push @result,[ $wi1,$wipr->@[1..$#$wipr],$widesc->@[1..$#$widesc] ];
last;
}
}
}
这很慢。如果有N个WI,则内循环执行N*N/2次。这意味着花费的时间与 N2 的平方成正比。
当某件事占用资源(例如时间)与 N2 的平方成正比时,我们说它是 O(N2)。
上述速度如此缓慢的原因是匹配记录的过程。如果数组被排序怎么办?
@wiprs = sort { $a->[0] <-> $b->[0] } @wiprs;
@widescs = sort { $a->[0] <-> $b->[0] } @widescs;
my $pr_i = 0;
my $desc_i = 0;
my @results;
while ($pr_i < @wiprs && $desc_i < @widescs) {
my $wipr = $wiprs[$pr_i];
my $widesc = $widescs[$desc_i];
my $wi1 = $wipr->[0];
my $wi2 = $wipdesc->[0];
my $cmp = $wi1 <=> $wi2;
if ($cmp < 0) {
++$pr_i;
}
elsif ($cmp > 0) {
++$desc_i;
}
else {
push @result,$widesc->@[1..$#$widesc] ];
++$pr_i;
++$desc_i;
}
}
这是 O(N log N)。这是很多更好。
如果我们假设有两个数组都具有相同的 WI,则上述简化为:
die "Bad data\n" if @wiprs != @widescs;
@wiprs = sort { $a->[0] <-> $b->[0] } @wiprs;
@widescs = sort { $a->[0] <-> $b->[0] } @widescs;
my $pr_i = 0;
my $desc_i = 0;
my @results;
while ($pr_i < @wiprs && $desc_i < @widescs) {
my $wipr = $wiprs[$pr_i];
my $widesc = $widescs[$desc_i];
my $wi1 = $wipr->[0];
my $wi2 = $wipdesc->[0];
die "Bad data\n" if $wi1 != $wi2;
push @result,$widesc->@[1..$#$widesc] ];
++$pr_i;
++$desc_i;
}
当然,如果数组已经排序,则简化为以下 O(N) 解决方案:
die "Bad data\n" if @wiprs != @widescs;
my $pr_i = 0;
my $desc_i = 0;
my @results;
while ($pr_i < @wiprs && $desc_i < @widescs) {
my $wipr = $wiprs[$pr_i];
my $widesc = $widescs[$desc_i];
my $wi1 = $wipr->[0];
my $wi2 = $wipdesc->[0];
die "Bad data\n" if $wi1 != $wi2;
push @result,$widesc->@[1..$#$widesc] ];
++$pr_i;
++$desc_i;
}
最后,我们通过首先构建索引得到了一个没有上述假设的 O(N) 解决方案。
my %widescs_lookup;
for my $widesc (@widescs)
my $wi = $widesc->[0];
$widescs_lookup{$wi} = $widesc;
}
my @results;
for my $wipr (@wiprs)
my $wi = $wipr->[0];
my $wi_desc = $widescs_lookup{$wi}
or next;
push @result,$widesc->@[1..$#$widesc] ];
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。