使用perl生成数字序列

时间:2014-08-07 19:01:30

标签: perl perl-data-structures

我正在尝试使用perl:

生成如下的数字序列
1
2 3
4 5 6
7 8 9 10
11 .. n

其中n是用户输入。 所以我提出了下面的逻辑,看起来很新手。希望有人能做得更好。

$a   = <STDIN>;
$ln  = 1;
$val = 1;
$itr = 1;

do {
    do {
        if ($val <= $a) {
            print "$val\t";
        } else {
            print "\n";
            exit;
        }
        $val++;
        $itr++;
    } while($itr <= $ln);
    $ln++;
    $itr = 1;
    print "\n";
} while ($a > 0);

3 个答案:

答案 0 :(得分:4)

欢迎使用Perl和StackOverflow。我有几点指示你:

  • 始终在每个perl脚本中加入use strict;use warnings;

  • 不要忘记从STDIN提取chomp你的意见。

  • 避免将do BLOCK与语句修饰符一起使用。而是始终使用whilefor循环。

  • 避免将$a$b用作sort保留的变量名。

应用这些更改,并使我们使用数学来确定我们是否在一行结尾处提供以下脚本:

use strict;
use warnings;

chomp(my $number = <STDIN>);

my $line = 1;

for my $iter (1 .. $number) {
    if ($iter == $line * ($line + 1) / 2 || $iter == $number) {
        print "$iter\n";
        $line++;
    } else {
        print "$iter\t";
    }
}

输出(输入为17):

17
1
2       3
4       5       6
7       8       9       10
11      12      13      14      15
16      17

使用二次方程

的替代方案

使用单一语句也可以获得想象并获得相同的输出:

my $number = 17;

for (1 .. $number) {
    print $_, ((sqrt(8 * $_ + 1) - 1) / 2) !~ /\./ || $_ == $number ? "\n" : "\t";
}

答案 1 :(得分:2)

#!/usr/bin/perl
use strict;

my $number = 1;
print "Enter a number: ";
my $n = <STDIN>;


for ( my $i = 0; $i < $n ; $i++)
{
  for (my $j = 0; $j < $i ; $j++)
   {
     while ($number<=$n)
     {
        print "$number ";
        $number++;
        last;
     }
   }

  if ( $number <= $n)
  {
    print "\n";
  }  
}

很好的编辑。你的代码有效,但我想采取非标准的方法,在你的答案中提出一些改进。

这不是典型的方法,我们可以(并且可能应该)在您有机会考虑信息后编辑本节。但是,既然你是一个刚开始帮助其他程序员的人,我想做一些特别的努力:

  • 始终在每个perl脚本中同时包含use strict;use warnings;

    这是我们可以与任何初级Perl程序员共享的#1提示,以及相当数量的中级程序员。任何时候新程序员都不使用其中一个pragma,最好先向他们指出。这对于声誉低于10的新SO用户来说最为常见。在我们演示的代码中总是模拟这些编译指示的使用情况也是一个好主意,即使它对示例的功能并不重要。

  • 研究perlstyle以获取有关perl代码的建议格式提示。

    每个人都有权拥有自己的风格,但你会发现大多数perl编码器都采用了一定的间距标准。这不是一个规则,只是一个建议。但是你会注意到我将在我的代码微调中更改格式。

  • 选择有意义的变量名称。

    切勿使用单字母变量名称。这不仅仅是为了其他程序员的利益,也是为了您自己的利益,从现在起6个月。给变量一个有意义的名称总是值得的,因为这是你可以使代码自我记录的第一种方式。

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    print "Enter a number: ";
    my $max = <STDIN>;
    
    my $number = 1;
    
    for ( my $row = 0; $row < $max ; $row++) {
        for (my $col = 0; $col < $row ; $col++) {
            while ($number <= $max) {
                print "$number ";
                $number++;
                last;
            }
        }
    
        if ( $number <= $max) {
            print "\n";
        }  
    }
    

    如果您觉得想要使用基本变量名称,请改用默认变量$_

    for (MIN .. MAX) {
    

    如果$_因任何原因无效,那么您应该使用有意义的变量名称。

  • 始终从<STDIN>

    输入chomp

    无论在哪种情况下,您的脚本都能正常运行。但是,有很多问题在本网站上发布,因为一些初学者没有chomp他们的输入,然后他们试图在open语句中使用文件名或在一个变量中使用比较。

    为了避免这些微妙的错误,只是为了塑造良好的习惯,总是要展示chomp输入,即使它不是绝对必要的。

    chomp(my $max = <STDIN>);
    
  • 我建议使用计数循环而不是C风格的for循环。

    此外,由于您只是在计算,我建议从1开始并以您的最大数字结束:

    for my $row ( 1 .. $max ) {
        for my $col ( 1 .. $row ) {
    
  • 您对while (COND) {...; last;}的使用与简单if声明同义:

            if ($number <= $max) {
                print "$number ";
                $number++;
            }
    
  • 你实际上在迭代什么?

    如果你考虑一下,你实际上是在尝试迭代$number变量。变量$row$col实际上是用于格式化的状态变量。因此,将逻辑完全反转为以下内容是有意义的:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    print "Enter a number: ";
    chomp( my $max = <STDIN> );
    
    my $row = 1;
    my $col = 1;
    
    for my $number ( 1 .. $max ) {
        if ($col == $row || $number == $max) {
            $row++;
            $col = 1;
            print "$number\n";
        } else {
            $col++;
            print "$number ";
        }
    }
    

    这个最终版本的好处是不会不必要地循环通过不打印的行。它与我的第一个解决方案有一个不足为奇的相似之处,除了它包含两个状态变量而不是我的一个。

总的来说,我认为这个最终解决方案对于这个OP的初学者程序员来说实际上可能是一个更好的建议,所以我将对这个答案进行投票。在您阅读这些评论后,请随时删除除最终答案之外的所有内容。

注意:我不会再次编辑这样的问题。通常,这种做法只是编辑问题并在编辑摘要中提供解释。但是,我有很多想分享的东西,希望将来有所帮助。欢迎来到SO并感谢帮助其他人。

答案 2 :(得分:0)

要回答原始问题的字面标题,或在 perl 中生成有限的整数序列:

#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper qw(Dumper);
my @monthn = (1..12);
print Dumper \@monthn;

这会产生

$VAR1 = [
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12
        ];