1

编辑:已解决。请参阅下面的解决方案。

我为前 10 个数字编写了以下斐波那契数列程序;但是我无法让它工作。它一直告诉我,Use of uninitialized value $secondLast in addition (+) at fib.plx line 22.它永远运行。我是初学者 Perl 程序员,所以我确信错误非常简单。谢谢。

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

sub fib(\@$);

my @defaultNums = (1,1);
my $max = 10;
fib(@defaultNums,10);

sub fib(\@$)
{
        my $nums_ref = $_[0];
        my $max = $_[1];
        foreach(@{$nums_ref})
        {
                print "$_, ";
        }
        print "\n";
        my $last = pop (@{$nums_ref});
        my $secondLast = pop (@{$nums_ref});
        my $sum = $last + $secondLast;
        push (@{$nums_ref}, $sum);
        if( scalar  @{$nums_ref} >= $max) { return; }
        fib (@{$nums_ref},$max);
        print "\n";
}

编辑:已解决。请参阅下面的解决方案。

4

2 回答 2

6

关于您的程序的一些注意事项:

  • 除非您完全确定自己在做什么,否则避免使用子程序原型很重要。原型主要用于编写 Perl 内置运算符的替代品,而这是很少需要的。您应该通过将调用编写为 来明确传递对数组的引用fib(\@defaultNums, 10)

  • 斐波那契数列的前两个值是零和一。您已经用第二个和第三个值播种了您的序列,虽然它可以正常工作,但在数学上并不正确。

  • 因为 Perl 对上下文很敏感,所以您可以删除scalar比较数组中元素数量的调用。您还可以使用if语句修饰符来避免很多噪音,因此您的return行变为return if @{$nums_ref} >= $max.

  • 您选择的解决方案 - 替换从数组中弹出的项目 - 效率低下且违反直觉。使用列表赋值和 Perl 从数组末尾索引数组元素的能力,您可以编写my ($last, $secondLast) = @{$nums_ref}[-1, -2]不会删除元素的元素,因此不需要替换它们。

这是您的程序的快速重写,以向您展示您所缺少的内容!

use strict;
use warnings;

my @defaultNums = (0, 1);

fib(\@defaultNums, 10);

sub fib {

  my ($nums_ref, $max) = @_;
  print join(', ', @$nums_ref), "\n";

  my ($last, $secondLast) = @{$nums_ref}[-1, -2];
  my $sum = $last + $secondLast;
  push @$nums_ref, $sum;
  return if @{$nums_ref} >= $max;

  fib($nums_ref, $max);
}

输出

0, 1
0, 1, 1
0, 1, 1, 2
0, 1, 1, 2, 3
0, 1, 1, 2, 3, 5
0, 1, 1, 2, 3, 5, 8
0, 1, 1, 2, 3, 5, 8, 13
0, 1, 1, 2, 3, 5, 8, 13, 21
于 2012-07-01T08:36:09.923 回答
2

我发现了我的错误。我每次都会从数组中弹出两次,所以我需要记住在推入 $sum 之前将这些数字推回。无论如何谢谢。

于 2012-06-30T20:11:38.653 回答