使用push和pop在Perl中反转并打印出一个数组?

时间:2015-12-07 23:08:23

标签: arrays perl push reverse pop

Perl新手。尝试几行代码逐个字符地手动反转并打印出来。 (是的,我知道这可以通过反向功能完成)。

首先,我有一个名为dummy.txt的虚拟文件

abcdefg1234567890

我的perl脚本在这里:

#! /usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my $file = 'dummy.txt';
my @reverse_array;

open (FH, '<', $file)
    or die ("Couldn't open $file : $!");

#split with empty string to get individual characters
my @chars = split("", <FH>); 

print "$#chars\n"; #prints 16, meaning there are 17 elements in @chars
print "@chars\n";  #prints a b c d e f g 1 2 3 4 5 6 7 8 9 0

for(my $i=0; $i <= $#chars; $i++) #iterate number of elements' times
{
    push @reverse_array, pop @chars; #pop the elements out of @chars into @reverse_array
}

print "$#reverse_array \n"; #prints 8, meaning there are 9 elements in @reverse_array
print "@reverse_array \n";  #prints 0 9 8 7 6 5 4 3 2, not as expected, but this is indeed 17 elements including the white space

close (FH)
    or die ("Failed to close $file: $!");

所以 pop 正在弹出空白。所以当我尝试用空字符串拆分时,拆分会添加空格?我还在考虑如何解决这个问题。非常喜欢你的输入,修改我的代码对我来说是最好的。谢谢。

-Jack

2 个答案:

答案 0 :(得分:4)

总是更喜欢迭代Perl中的列表,而不是使用丑陋的C风格的循环

你的循环

for (my $i=0; $i <= $#chars; $i++) {
    push @reverse_array, pop @chars;
}

相当于

my $i = 0;
while ( $i <= $#chars ) {
    push @reverse_array, pop @chars;
    ++$i;
}

所以$#chars从16开始。循环执行一次,现在$i为1而$#chars为15,因为pop。此过程将持续到循环的第八次迭代之后 - 当$i为8且$#chars为7时,测试现在失败,因此循环退出

这就是你正在反转@chars的最后八个元素,正如你所看到的那样

如果你写了

for my $i ( 0 .. $#chars ) {
    push @reverse_array, pop @chars;    
}

然后它不仅更清晰,更容易阅读,而且它也符合您的意图

字符串化数组时,空格来自Perl的行为。如果你写"@array\n",那么Perl会构建一个包含@array元素的字符串,用单个空格分隔。 (这是默认行为。您可以更改用于分隔元素的字符串,但我建议您不要去那里。)

要只打印数组的内容,您可以编写

print @chars, "\n"

你会看到你的期望

答案 1 :(得分:2)

您的问题是您在循环结构中使用$#chars,并且随着时间的推移而改变。您需要先保存它:

use strict;
use warnings;

my $str = 'abcdefghijklmnopqrstuvwxyz';

my @reversed;
my @chars = split //, $str;

my $elt_count = scalar @chars;

for ( 1 .. $elt_count ) {
    push( @reversed, pop @chars );
}

print @reversed;

但是你可以使用while循环轻松解决它:

use strict;
use warnings;

my $str = 'abcdefghijklmnopqrstuvwxyz';

my @reversed;
my @chars = split //, $str;

while ( @chars ) {
    push( @reversed, pop @chars );
}

print @reversed;

这取决于您在去的时候排空@chars这一事实,并在没有任何遗漏的情况下挽救。

您还应该意识到 -

之间存在差异
print "@reversed";

print @reversed; 

在前一种情况下,perl会插入空格,因为您已将数组转换为字符串。这就是为什么你会得到你的明显行为的原因。