Является ли моя подпрограмма Фибоначчи примером рекурсии в Perl? - PullRequest
4 голосов
/ 17 сентября 2010

Как мы все знаем, мы можем отправить любое количество аргументов в подпрограмму в 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";
<>;

Я знаю, что это неудачный пример ... но моя цель - узнать, будет ли этот тип реализации подходить для примера рекурсии?
Надеюсь, что нет кирпичной битой:)

Edit:

в зависимости от какого-либо условия, если программа решит отправить только один аргумент, два или несколько аргументов себе ... это будет действительной характеристикой?

Ответы [ 4 ]

4 голосов
/ 17 сентября 2010

Функция является рекурсивной, если она сама вызывает.Ваша recursion функция вызывает сама себя, поэтому она рекурсивная.Условия codaddict необходимы для того, чтобы рекурсивная функция работала правильно , но функция все равно могла бы быть рекурсивной, если бы они не были выполнены.(Это было бы просто рекурсивно и с ошибками.)

2 голосов
/ 17 сентября 2010

Ваша программа работает и она рекурсивна, и это отличное место для начала. Однако его трудно читать и он не очень гибкий в использовании. Вот альтернатива с несколькими предложениями:

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);
2 голосов
/ 17 сентября 2010

Да.Это рекурсивная функция.Он соответствует требуемым условиям

  • Должен быть способ прекратить рекурсию.В вашем случае, когда $_[0] становится 5
  • Рекурсивный вызов должен двигаться к завершающему регистру.Вы передаете $_[0] + 1 рекурсивным вызовам.
0 голосов
/ 16 сентября 2015

Числа Фибоначчи - это любимый способ демонстрации рекурсии (наряду с факториалом, который я использую в Мастеринг 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";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...