Is my Fibonacci subroutine an example of recursion in Perl?
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 c开发者_JS百科ondition, if the program decides to send only one argument or two or multiple arguments to itself… would that be a valid characteristic?
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.)
Yes. Its a recursive function. It meets the required conditions of
- There should be a way to terminate
recursion. In your case when
$_[0]
becomes5
- Recursive call should move towards
the terminating case. You pass
$_[0] + 1
to recursive calls.
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);
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";
精彩评论