Perl 中的数组初始化

Posted

技术标签:

【中文标题】Perl 中的数组初始化【英文标题】:Array initialization in Perl 【发布时间】:2011-03-16 03:43:52 【问题描述】:

如何将数组初始化为 0?

我试过了。

my @arr = ();

但它总是给我一个警告,“使用未初始化的值”。我事先不知道数组的大小。我动态填充它。我认为上面的代码应该将其初始化为 0。

我该怎么做?

【问题讨论】:

向我们展示您遇到问题的代码。 为什么你需要将它设置为0? XY problem 与此类似。我有另一个数组,其数字如 [0,0,0,1,2,2,3,3,3,4] 现在我必须计算 0,1,2,3,4 的数量,所以我将使用另一个数组...并将计数存储在给定的索引中。所以我会有 arr[0] = 3 arr[1] = 1 arr[2] = 2 arr[3] = 3 arr[4] = 4 所以当我遇到一个元素时我会... arr[i ] = arr[i] + 1;为此,我需要从用 0 初始化的元素开始。上面的代码有效。但它也会引发警告。 你可以用 $arr[i]++ 代替 $arr[i] = $arr[i] + 1;此外,如果您的数组为空,$arr[i]++ 仍会将 $arr[i] 设置为 1; @MkV $arr[i] += 1; 在某些情况下可能会更好,++ 在 Perl 中有一些魔力,导致它有点慢。 @Ven'Tatsu:你对此有什么引用(减速)吗?我知道当它是 undef(预转换为 0)或字符串时有魔力。在进行基准测试时,我没有看到明显的速度差异(>1 微秒)。 【参考方案1】:

如果我理解你,也许你不需要一个零数组;相反,您需要一个散列。哈希键将是另一个数组中的值,哈希值将是该值在另一个数组中存在的次数:

use strict;
use warnings;

my @other_array = (0,0,0,1,2,2,3,3,3,4);
my %tallies;
$tallies$_ ++ for @other_array;

print "$_ => $tallies$_\n" for sort $a <=> $b keys %tallies;    

输出:

0 => 3
1 => 1
2 => 2
3 => 3
4 => 1

要更直接地回答您的具体问题,创建一个填充了一堆零的数组,您可以使用以下两个示例中的技术:

my @zeroes = (0) x 5;            # (0,0,0,0,0)

my @zeroes = (0) x @other_array; # A zero for each item in @other_array.
                                 # This works because in scalar context
                                 # an array evaluates to its size.

【讨论】:

谢谢。棒极了。但仍然想知道,为什么我不能在不使用哈希的情况下将数组元素初始化为 0。问题是它可以正常工作,但在访问未初始化的值之前会给我一个警告。 @jerrygo:你有没有机会使用旧版本的 perl?上面的这段代码不应该给你任何警告。 @Ether:奇怪。我使用草莓 perl 5.16 版,但仍然收到警告消息。为了避免这种情况,我插入了一个条件:if (def $value) push(@array,$value) else push(@array,"") .【参考方案2】:

“将数组初始化为零”是什么意思?数组不包含“零”——它们可以包含“零元素”,这与“空列表”相同。或者,您可以有一个包含一个元素的数组,其中该元素为零:my @array = (0);

my @array = (); 应该可以正常工作——它分配一个名为@array 的新数组,然后为其分配一个空列表()。请注意,这与简单地说 my @array; 相同,因为新数组的初始值无论如何都是空列表。

您确定您从这一行得到错误,而不是代码中的其他地方吗?确保您的模块或脚本中有use strict; use warnings;,并检查您收到的错误的行号。 (在这里发布一些上下文代码也可能会有所帮助。)

【讨论】:

对不起。是的。我想将数组的元素初始化为 0。这样我就可以将数组用作每个索引的某种计数器。具体问题请参考上面的评论。 如果你想初始化一个数组,使其具有与另一个数组相同数量的元素,所有特定值;做类似的事情;我的@arr2 = (0) x @arr1; @MkV: 或my @arr2=(0) x $#arr1 也是,不是吗? @jerrygo:您不需要将数组显式初始化为全零;如果你从一个空数组中执行$array[$i]++,一切都会“正常工作”。 @drewk:不,$#arr1scalar(@arr1) 不同。对于一个有五个元素的数组,前者是 4,后者是 5(假设您没有更改 $[ 的默认值)。【参考方案3】:

要在您对帖子的评论中生成输出,可以这样做:

use strict;
use warnings;

my @other_array = (0,0,0,1,2,2,3,3,3,4);
my @array;
my %uniqs;

$uniqs$_++ for @other_array;

foreach (keys %uniqs)  $array[$_]=$uniqs$_ 

print "array[$_] = $array[$_]\n" for (0..$#array);

输出:

   array[0] = 3
   array[1] = 1
   array[2] = 2
   array[3] = 3
   array[4] = 1

这与您所说的生成具有零值的并行数组的算法不同,但它是一种更 Perly 的方式...

如果您必须有一个与第一个数组大小相同且元素初始化为 0 的并行数组,则此语句将动态执行此操作:@array=(0) x scalar(@other_array); 但实际上,您不需要这样做。

【讨论】:

以上是关于Perl 中的数组初始化的主要内容,如果未能解决你的问题,请参考以下文章

Perl如何检查数组是不是仍然为空?

小白学Perl之初始哈希

Perl:使用正则表达式将十六进制编码的字符串解析为数组

数组及其在内存中的分配

数组及其在内存中的分配

c语言学习--数组