嵌套循环问题

时间:2016-06-12 21:07:02

标签: perl

我有一个名为numbers.txt的文件,它基本上与5个数字对齐: 它们看起来像这样:

1 2 3 4 5

我想要实现的是我想从行中读取这些数字(已经有效),然后在每次迭代中我想为从该文件读取的每个数字添加+1并在屏幕上打印它们有了打印,所以最终的结果应该是这样的:

1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9

#!/usr/bin/perl

use strict;
use warnings;

open("handle", 'numbers.txt') or die('unable to open numbers file\n');
$/ = ' ';

OUT: for my $line (<handle>) {
        for (my $a = 0; $a < 5; $a++) {
            chomp $line;
            $line += 1;
            print "$line ";
                next OUT;
        }
}
close("handle");

暂时没有在perl中完成循环,如果有人可以提供工作示例,那就太棒了。

另外,如果您能提供多个工作示例,那将是非常好的,只是为了将来证明;) 感谢

5 个答案:

答案 0 :(得分:1)

您可以尝试使用此尺寸。

#!/usr/bin/perl

use strict;
use warnings;

open("handle", 'numbers.txt') or die('unable to open numbers file\n');

for my $line (<handle>) {
    chomp $line;
    for my $number (split /\s+/, $line) {
        for (my $a = $number; $a < $number+5; $a++) {
            print "$a ";
        }       
        print "\n";
    }
}
close("handle");

您可以省去 $ / =&#39; &#39; 而是让外循环迭代文件的行。
对于每个要用空格分隔的数字进行迭代的每一行,因此 split / \ s + /,$ line 会为您提供内部循环的数字列表。 对于您的输出$ a从文件读取的数字开始。

答案 1 :(得分:1)

这将完成您的工作:

use strict;
use warnings;

while(<DATA>) {
    chomp;
    print "$_\n";
    my @split = split;
    my $count = 0;
    for (1..4){
        $count++;
        foreach (@split){ 
            my $num = $_ + $count;
            print "$num ";
        }
        print "\n";
    }

}

__DATA__
1 2 3 4 5

答案 2 :(得分:1)

更新添加了另一种方法,这个方法与发布的方法一致。

增加字符串中的每个数字,更改字符串。重复一遍。以下是两种方法。另一种方法是读取单个数字并按照整数序列打印。

(1)使用正则表达式。它也适合单线

echo "1 2 3 4 5" | perl -e '$v = <>; for (1..5) { print $v; $v =~ s/(\d+)/$1+1/eg; }'

这将打印所需的输出。但最好把它放在脚本中

use warnings;
use strict;

my $file = 'numbers.txt';
open my $fh, '<', $file or die "can't open $file: $!";

while (my $line = <$fh>) {  
    # Add chomp($line) if needed for some other processing.
    for (1..5) {
        print $line;
        $line =~ s/(\d+)/$1+1/eg;
    }   
}

/e修饰符对此至关重要。它使得正则表达式的替换方被评估为代码而不是双引号字符串。所以你实际上可以在那里执行代码,在这里我们为每个匹配的数字添加捕获的数字$1+1,因为/g向下移动字符串。这会更改字符串,以便for (1..5)的下一次迭代递增那些,等等。我匹配多个数字\d+,这在您的示例中不是必需的,但通常会更有意义。

(2)通过split + map + join,也反复更改线路

while (my $line = <$fh>) {
    for (1..5) {
        print $line;
        $line = join ' ', map { $_+1 } split '\s+', $line;            
    }
}

split获取$line中的数字列表并将其提供给mapjoin将每个数字递增,将其输出列表提供给$line。已连接的字符串将分配回\s+,并重复此操作。我按' '分割以允许多个空格,但这使得它接受的输入格式非常“放松”,请参阅perlrecharclass。如果您知道它是一个空格,请将其更改为open my $fh, '<', $file or die "can't open $file: $!"; local $/ = ' '; while (my $num = <$fh>) { print "$_ " for $num..$num+4; print "\n"; }

(3)一次取一个数字并从中打印整数序列。

4

可以通过预处理整行来编码神奇的my $len = () = $line =~ /(\d+)/g; 以查找序列长度,例如

split

scalar - 进入数组并获取$len-1,然后使用open my $fh, '<', $file

补充评论。

  • 我建议使用三参数open die "Your message: $!"

  • 检查通话时,请打印错误if ($bad) { die "Got $bad" },以查看失败的原因。如果决定退出$!,那么您可能不需要$!。但是当外部呼叫失败时,您不知道原因,因此您需要合适的错误变量,通常是{{1}}。

答案 3 :(得分:1)

这里不需要使用嵌套循环它总是使程序变慢。

#!/usr/bin/perl
use strict;
use warnings;

my @num = split(" ",(<DATA>)[0]);  

foreach my $inc (0..$#num)
{
    print map{$inc+$_," "}@num;  # Add one by one in array element
    print "\n";
}


__DATA__
1 2 3 4 5

答案 4 :(得分:0)

您的计划存在许多问题。这是阻止它工作的原因

  • 您正在将记录分隔符设置为单个空格。您的输入文件包含"1 2 3 4 5\n",因此while循环将重复五次,将$line设置为"1 ""2 ""3 ",{{1 },"4 "

  • 您的"5\n"循环设置为迭代五次。它会for删除数字后的空格,然后递增chomp $line并打印它。然后你跳出$line循环,只用for执行一次。这会导致文件中的每个值加1并打印,因此您得到next OUT

  • 删除不必要的2 3 4 5 6,产生更接近的东西

    next OUT

    现在输入文件中的每个数字都会打印五个数字

  • 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10 循环后添加print "\n"帮助分隔行

    for
  • 现在我们需要在之前打印数字,而不是之后。如果我们交换2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10 $line += 1,我们就会得到这个

    print "$line "

    这里发生的是1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9 仍然是一个换行符,现在出现在输出中。 5不会删除此内容,因为它会从字符串末尾删除chomp的值。您已将其设置为空格,因此它将仅删除空格。修复方法是用替换$/替换chomp,替换*字符串中的所有空格。你还需要这样做一次,所以我把它放在顶部的s/\s+//g循环之外

现在我们得到这个

for

这是你的代码,因为它结束了

    1 2 3 4 5 
    2 3 4 5 6 
    3 4 5 6 7 
    4 5 6 7 8 
    5 6 7 8 9 

还有一些其他最佳做法可以改善您的计划

  • 使用use strict; use warnings; open( "handle", 'numbers.txt' ) or die('unable to open numbers file\n'); $/ = ' '; for my $line (<handle>) { $line =~ s/\s+//g; for ( my $a = 0; $a < 5; $a++ ) { print "$line "; $line += 1; } print "\n"; } close("handle");

  • 使用词法文件句柄和use warnings 'all'

  • 的三参数形式
  • 如果要更改Perl的内置变量,请使用open

  • local放入您的$!字符串中,以便您知道为什么 die失败

  • 避免使用C风格的open循环,而是迭代列表

这些修复也是这样的。输出与上面的

相同
for