Arrays Perl-构建数组数组会导致溢出
我试图分析hashmap,寻找重复的值,并在数组中获取它们的键。这些数组将位于数组的数组中。顺便说一下,我是个新手。然而,当我启动它时,它从未停止运行。我错在哪里Arrays Perl-构建数组数组会导致溢出,arrays,perl,Arrays,Perl,我试图分析hashmap,寻找重复的值,并在数组中获取它们的键。这些数组将位于数组的数组中。顺便说一下,我是个新手。然而,当我启动它时,它从未停止运行。我错在哪里 while (($k,$v)=each %hashmap){ $hasduplicate = 0; delete $hashmap{$k}; @dups = (); while (($k1,$v1) = each %hashmap){ if ($v
while (($k,$v)=each %hashmap){
$hasduplicate = 0;
delete $hashmap{$k};
@dups = ();
while (($k1,$v1) = each %hashmap){
if ($v1 eq $v) {
$hasduplicate = 1;
push @dups, $k1;
delete $hashmap{$k1};
}
}
if ($hasduplicate){
push (@dups, $k);
push @dupsarray, [@dups];}
}
在Perl中,每个哈希只有一个与其自身对齐的迭代器(请参阅)。因此,在调用
each
的循环中为相同的哈希运行each
并不是按照您的想法进行的
如果要查看发生了什么,请尝试在外部循环的开始处添加以下行:
warn $k;
变量名前缺少几个美元符号。例如,您可能希望删除$hashmap{$k}
,而不是$hashmap{k}
,这相当于$hashmap{'k'}
要输出数组数组,必须取消对内部数组的引用:
print map "@$_\n", @dupsarray;
顺便说一句,我会使用数组散列来解决您的任务。以下是方法:
my %dups;
while (my ($k, $v) = each %hashmap) {
push @{ $dups{$v} }, $k;
}
for my $k (grep @{ $dups{$_} } > 1, keys %dups) {
print "$k: @{ $dups{$k} }\n";
}
在Perl中,每个哈希只有一个与其自身对齐的迭代器(请参阅)。因此,在调用
each
的循环中为相同的哈希运行each
并不是按照您的想法进行的
如果要查看发生了什么,请尝试在外部循环的开始处添加以下行:
warn $k;
变量名前缺少几个美元符号。例如,您可能希望删除$hashmap{$k}
,而不是$hashmap{k}
,这相当于$hashmap{'k'}
要输出数组数组,必须取消对内部数组的引用:
print map "@$_\n", @dupsarray;
顺便说一句,我会使用数组散列来解决您的任务。以下是方法:
my %dups;
while (my ($k, $v) = each %hashmap) {
push @{ $dups{$v} }, $k;
}
for my $k (grep @{ $dups{$_} } > 1, keys %dups) {
print "$k: @{ $dups{$k} }\n";
}
问题是每个散列只能有一个
序列,因为只有一个索引来跟踪下一个键/值对
此外,您在一些地方使用了k
和k1
,您的意思是$k
和$k1
。在每个Perl程序的顶部,必须始终使用strict
和使用warnings
。这会提醒你注意这个问题
您可以通过对我的$k1(键%hashmap){…}
使用来解决这个问题。这将创建一个单独的键列表,依次分配给$k1
,这样就不会多次使用迭代器
对代码的修改符合我的要求
use strict;
use warnings;
my %hashmap = (
a => 'a',
b => 'b',
c => 'a',
d => 'c',
);
my @dupsarray;
while (my ($k, $v) = each %hashmap) {
my $hasduplicate = 0;
delete $hashmap{$k};
my @dups;
for my $k1 (keys %hashmap) {
my $v1 = $hashmap{$k1};
if ($v1 eq $v) {
$hasduplicate = 1;
push @dups, $k1;
delete $hashmap{$k1};
}
}
if ($hasduplicate) {
push(@dups, $k);
push @dupsarray, [@dups];
}
}
use Data::Dump;
dd \@dupsarray;
输出
[["a", "c"]]
[["c", "a"]]
一个更简单的方法是创建一个反向散列,其中交换原始散列的键和值。然后只需选择包含多个元素的反转哈希值。本程序演示
use strict;
use warnings;
my %hashmap = (
a => 'a',
b => 'b',
c => 'a',
d => 'c',
);
my @dupsarray = do {
my %inverted;
while (my ($k, $v) = each %hashmap) {
push @{ $inverted{$v} }, $k;
}
grep { @$_ > 1 } values %inverted;
};
use Data::Dump;
dd \@dupsarray;
输出
[["a", "c"]]
[["c", "a"]]
问题是每个散列只能有一个序列,因为只有一个索引来跟踪下一个键/值对
此外,您在一些地方使用了k
和k1
,您的意思是$k
和$k1
。在每个Perl程序的顶部,必须始终使用strict
和使用warnings
。这会提醒你注意这个问题
您可以通过对我的$k1(键%hashmap){…}
使用来解决这个问题。这将创建一个单独的键列表,依次分配给$k1
,这样就不会多次使用迭代器
对代码的修改符合我的要求
use strict;
use warnings;
my %hashmap = (
a => 'a',
b => 'b',
c => 'a',
d => 'c',
);
my @dupsarray;
while (my ($k, $v) = each %hashmap) {
my $hasduplicate = 0;
delete $hashmap{$k};
my @dups;
for my $k1 (keys %hashmap) {
my $v1 = $hashmap{$k1};
if ($v1 eq $v) {
$hasduplicate = 1;
push @dups, $k1;
delete $hashmap{$k1};
}
}
if ($hasduplicate) {
push(@dups, $k);
push @dupsarray, [@dups];
}
}
use Data::Dump;
dd \@dupsarray;
输出
[["a", "c"]]
[["c", "a"]]
一个更简单的方法是创建一个反向散列,其中交换原始散列的键和值。然后只需选择包含多个元素的反转哈希值。本程序演示
use strict;
use warnings;
my %hashmap = (
a => 'a',
b => 'b',
c => 'a',
d => 'c',
);
my @dupsarray = do {
my %inverted;
while (my ($k, $v) = each %hashmap) {
push @{ $inverted{$v} }, $k;
}
grep { @$_ > 1 } values %inverted;
};
use Data::Dump;
dd \@dupsarray;
输出
[["a", "c"]]
[["c", "a"]]
循环内循环方法所用的时间与元素数量的平方成正比。底部的解决方案所花费的时间与散列中的元素数成比例。后者的可伸缩性要好得多。循环内循环方法所用的时间与元素数量的平方成正比。底部的解决方案所花费的时间与散列中的元素数成比例。后者的伸缩性要好得多。