我的Fibonacci子例程是Perl中递归的一个例子吗?

时间:2010-09-17 07:26:54

标签: perl recursion

众所周知,我们可以向Perl中的子例程发送任意数量的参数。 以下示例是否正确显示了递归以显示斐波那契数列(5个值)?

#!/usr/bin/perl -w

use strict;

sub recursion
{
  if ($_[0] && $_[2])
  {
    print $_[2],"\n";
    if ($_[0] < 5)
    {
       return recursion($_[0] + 1, $_[2], $_[1] + $_[2]);
    }
    else
    {
       return $_[0];
    }
  }
  elsif ($_[0] && !$_[1] && !$_[2])
  {
    print "0\n";
    return recursion($_[0], 0, 1);
  }
}
print "\nFibo Series : \n";
recursion(1);

print "\nEnter to exit";
<>;

我知道这是一个蹩脚的例子......但我的目的是要知道这种类型的实现是否仍然有资格作为递归的例子?
希望没有砖块:)

修改

取决于某些条件,如果程序决定只向自己发送一个参数或两个或多个参数......那么这是一个有效的特征吗?

4 个答案:

答案 0 :(得分:4)

如果函数调用自身,则该函数是递归的。您的recursion函数调用自身,因此它是递归的。 codaddict的条件对于正常工作的递归函数是必要的,但如果不满足函数仍然可以递归。 (它只是递归的错误。)

答案 1 :(得分:2)

是。它是一个递归函数。它符合

的要求条件
  • 应该有办法终止 递归。在$_[0]成为5
  • 的情况下
  • 递归呼叫应该走向 终止案件。您将$_[0] + 1传递给递归调用。

答案 2 :(得分:2)

你的程序有效,它是递归的,这是一个很好的起点。但是,它很难阅读,并且使用起来不够灵活。这是一个替代方案,有一些建议:

use strict;
use warnings;

sub fib_up_to {
    # Unpack @_ for readability and maintainability.
    my ($max, $i, $j) = @_;

    # Handle the first call by the user, who normally would supply only the max.
    # Note that we test whether $i and $j are defined rather than just
    # evaluating their truth: 0 is defined but false in Perl.
    ($i, $j) = (0, 1) unless defined $i and defined $j;
    return unless defined $max and $max >= 0;

    # Check for terminal condition.
    return if $i > $max;

    # Do stuff and then recurse.
    print $i, "\n";
    fib_up_to($max, $j, $i + $j);
}

# Give your function a meaningful name. Also, let it be run from the command
# line, which is handy during development. For example:
#
# perl fib_up_to.pl 100
# perl fib_up_to.pl 100 8 13
fib_up_to(@ARGV);

答案 3 :(得分:0)

斐波纳契数是展示递归的最佳方式(以及我在Mastering Perl中使用的因子)。你的例子很好,但你也应该知道在很多情况下你不需要这个功能。

这是一个迭代解决方案,它从低端而不是高端构建序列。您无需递归,因为您已经知道下一步所需计算的答案:

use v5.20;

use experimental qw(signatures);
no warnings qw(experimental::signatures);

sub fibonacci ( $n ) {
    my @numbers = qw( 0 1 );

    foreach ( 2 .. $n ) {
        $numbers[ $_ ] = $numbers[ $_ - 1 ] + $numbers[ $_ - 2 ];
        }

    return @numbers[ 0 .. $n ];
    }

my @series = fibonacci( 1 );
say "Fibo Series : @series";

它变得更好,因为你可以修改它以使用state来记住以前的计算。您必须使用数组引用,因为state无法初始化数组,但这不是什么大问题:

use v5.22;

use experimental qw(signatures postderef);
no warnings qw(experimental::signatures experimental::postderef);

sub fibonacci ( $n ) {
    state $numbers = [ qw( 0 1 ) ];

    foreach ( $#$numbers .. $n ) {
        $numbers->[ $_ ] = $numbers->[ $_ - 1 ] + $numbers->[ $_ - 2 ];
        }

    return $numbers->@[ 0 .. $n ];
    }

my @series = fibonacci( 17 );
say "Fibo Series : @series";