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

发布于 2024-09-19 08:15:16 字数 687 浏览 3 评论 0原文

众所周知,我们可以向 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";
<>;

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

编辑:

根据某些条件,如果程序决定只向自身发送一个参数或两个或多个参数......这会是一个有效的特征吗?

As we all know that we can send any number of arguments to a subroutine in Perl.
Would the following example be a correct demonstration of recursion to display fibonacci series (5 values)?

#!/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";
<>;

I know it is a lame example… but my aim is to know whether this type of implementation would still qualify to be an example for recursion?
Hoping for no brickbats :)

Edit:

depending upon some condition, if the program decides to send only one argument or two or multiple arguments to itself… would that be a valid characteristic?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

〃温暖了心ぐ 2024-09-26 08:15:16

如果函数调用自身,则该函数是递归的。您的递归函数会调用自身,因此它是递归的。 codaddict 的条件是递归函数正常工作所必需的,但如果不满足这些条件,函数仍可能是递归的。 (这只是递归错误。)

A function is recursive if it calls itself. Your recursion function calls itself, so it's recursive. codaddict's conditions are necessary for a recursive function to work properly, but a function could still be recursive if they weren't met. (It would just be recursive and buggy.)

是的。它是一个递归函数。它满足所要求的条件

  • 应该有办法终止
    递归。在您的情况下,当 $_[0] 变为 5 时,
  • 递归调用应该转向
    终止的情况。您将 $_[0] + 1 传递给递归调用。

Yes. Its a recursive function. It meets the required conditions of

  • There should be a way to terminate
    recursion. In your case when $_[0] becomes 5
  • Recursive call should move towards
    the terminating case. You pass $_[0] + 1 to recursive calls.
半枫 2024-09-26 08:15:16

您的程序可以运行并且是递归的,这是一个很好的起点。然而,它很难阅读,而且使用起来也不太灵活。这是一个带有一些建议的替代方案:

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);

Your program works and it is recursive, which is a great place to start. However, it's difficult to read and is not very flexible in its usage. Here's an alternative with a few suggestions:

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);
李不 2024-09-26 08:15:16

斐波那契数是演示递归的最喜欢的方式(以及我在 掌握 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";

The Fibonacci numbers are a favorite way to demonstrate recursion (along with factorial which I use in Mastering Perl). Your example is fine, but you should also know that you don't need that feature in many cases.

Here's an iterative solution that builds up the sequence from the low end instead of the high end. You don't have to recurse because you already know the answers to the computations you need for the next step:

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";

It gets even better because you can modify this to use state to remember the previous computations. You have to use an array reference since state can't initialize an array, but that's not a big deal:

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";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文