【问题标题】:Nested for loop in perlperl中的嵌套for循环
【发布时间】:2014-01-03 01:45:42
【问题描述】:

我正在尝试用 perl 中的嵌套“for”循环制作一个小脚本。 在我学习的过程中,起初我做了 3 个 for 循环,效果很好。为了使某些东西更智能,我想将它们嵌套起来,但我不知道出了什么问题。

如果我的输入文本是 ABCDEFGHI 我想获得

text 1 ABC DEF GHI
text 2 BCD EFG HI
text 3 CDE FGH I

但不是它,我的输出是

text1 ABC DEF GHI ABC DEF GHI ABC DEF GHI ABC DEF GHI ABC DEF GHI ABC DEF GHI ABC DEF GHI ABC DEF GHI ABC DEF GHI
text2 BCD EFG HI BCD EFG HI BCD EFG HI
text3 CDE FGH I

这是我的脚本。我正在使用 perl 5.18.1。

use Modern::Perl '2013';

my @text1;
my @text2;
my @text3;

my $entry = shift;
my $len = length $entry;

for (my $i = 2; $i < $len; $i += 3) {
    for (my $i = 1; $i < $len; $i += 3) {
        for (my $i = 0; $i < $len; $i += 3) {
            my $text = substr($entry, $i, 3);
            push @text1, uc($text);
        }
        my $text = substr($entry, $i, 3);
        push @text2, uc($text);
    }
    my $text = substr($entry, $i, 3);
    push @text3, uc($text);
}

say "text1 @text1";
say "text2 @text2";
say "text3 @text3";

我已经环顾四周了,这里是http://perldoc.perl.org/perlsyn.html#For-Loops

感谢您的帮助

【问题讨论】:

  • 我假设您只是想了解更多信息?如果是这种情况,您应该知道嵌套的 for 循环是您应该尽可能避免的事情,它们只会使您的程序运行得更慢。只需一个循环即可完成您想做的事情。
  • 是什么让你认为内循环不应该执行 27 次?
  • 是的。我正在努力学习更多。我认为 3 个独立的循环不是很聪明。所以,谢谢你的建议!
  • @Arkadiy 每次外部循环越多,内部循环就会重新开始……但不知道该怎么做。
  • @Tetraodienne “不是很聪明”并不是你想在这里使用的标准;相反,“完成工作”会更好地为您服务。 (嵌套循环也应尽可能避免,因为它们的复杂性成本。考虑一个运行十次的外循环和一个运行十次的内循环;整个过程必须经过 100 次迭代才能完成外循环。现在考虑一个运行十次的外循环和一个运行 一万次次的内循环......)

标签: perl loops nested


【解决方案1】:

我不知道你为什么想要三个嵌套循环(不包括substr)。您只需要两个:一个循环确定起始位置,一个循环遍历字符串。

my $text = uc('ABCDEFGHI');
for my $offset (0..2) {
   my @parts;
   for (my $i=$offset; $i<length($text); $i+=3) {
      push @parts, substr($work, $i, 3);
   }

   say "@parts";
}

或者没有substr。真正证明实际上只有两个循环:

my $text = uc('ABCDEFGHI');
my @text = split //, $text;
for my $offset (0..2) {
   my @parts;
   for my $i ($offset..$#text) {
      $parts[ ($i - $offset) / 3 ] .= $text[$i];
   }

   say "@parts";
}

就个人而言,我会使用

my $text = uc('ABCDEFGHI');
for (1..3) {
   my @parts = $text =~ /\G.{1,3}/sg;
   say "@parts";

   $text =~ s/^.//s;
}

【讨论】:

  • 我猜是使用print(..)时的个人喜好问题?这对于 perl 来说非常少见。
  • @mpapec,反对什么?
  • print ""print("") 更常见
  • @mpapec,您可以在子和函数调用中省略括号,但这很危险。例如,print(($x+$y)/2)print ($x+$y)/2 不同。
  • 不使用警告时? perl -we 'print (3+3)/2'
【解决方案2】:

您的三个循环不需要嵌套即可获得所需的输出:

use Modern::Perl '2013';

my @text1;
my @text2;
my @text3;

my $entry = shift;
my $len = length $entry;

for (my $i = 0; $i < $len; $i += 3) {
   my $text = substr($entry, $i, 3);
   push @text1, uc($text);
}

for (my $i = 1; $i < $len; $i += 3) {
   my $text = substr($entry, $i, 3);
   push @text2, uc($text);
}

for (my $i = 2; $i < $len; $i += 3) {        
    my $text = substr($entry, $i, 3);
    push @text3, uc($text);
}

say "text1 @text1";
say "text2 @text2";
say "text3 @text3";

可以也可以稍微重构一下,使用两个嵌套循环:

use Modern::Perl '2013';

my @texts = ( [], [], [] );

my $entry = shift;
my $len = length $entry;

for ( my $start = 0; $start < 3; $start++ ) {
  for ( my $i = $start; $i < $len; $i += 3 ) {
     my $text = substr($entry, $i, 3);
     push @{$texts[$start]}, uc($text);
  }
}

for ( my $start = 0; $start < 3; $start++ ) {
  say "text${start} @{$texts[$start]}";
}

顺便说一句:如果您确实嵌套了for 循环,那么如果您使用不同的变量作为迭代器,将会更容易阅读和理解您的代码。您拥有的三个 $i 变量将起作用,但我必须检查很长时间才能确保这不是您的问题。

【讨论】:

    猜你喜欢
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 2021-03-20
    相关资源
    最近更新 更多