perl中的fibonacci系列执行无限循环

时间:2014-02-28 11:39:30

标签: perl

您好我正在尝试使用perl执行带有递归函数的fibonacci系列。这是代码

#! /user/bin/perl

print "enter the number of elements for the series\n";
$value=<stdin>;
chomp($value);
print "\n\nThe value entered is $value\n\n";
for($i=0;$i<$value;$i++)
{
    print "fib($i)=".&fib($i);
    print "\n";
}


sub fib
{
    $rec=@_[0];

    print"In the subroutine rec is :".$rec."\n";
    if($rec == '0')
    {
        $f='0';
    }
    if($rec == '1')
    {
        $f='1';
    }
    else
    {
        $f=fib($rec-1)+fib($rec-2);
    }

    return $f;
}  

但是这段代码最终会陷入无限循环。任何人都可以帮助解决我所犯的错误。

3 个答案:

答案 0 :(得分:3)

如果$rec == 0

,我们会遇到问题
if($rec == '0')
{   # yes, this branch is being taken
    $f='0';
}
# ok, another conditional
if($rec == '1')
{   # nope
    $f='1';
}
else
{   # yes, this branch is taken: 0 != 1
    $f=fib($rec-1)+fib($rec-2);
}

...突然你正在执行fib(-1)

解决方案:使用elsif或立即返回

return 0 if $rec == 0;
return 1 if $rec == 1;
return fib($rec - 1) + fib($rec - 2);

下一个问题是您正在使用全局变量。如果$rec > 1,则会发生以下情况:

    正在计算
  • fib($rec -1),使用相同的$rec变量。
  • 最后,$rec == 0
  • 现在,我们计算fib($rec - 2),其开头为fib(-2)

解决方案:使用my的词法变量:

sub fib {
    my ($rec) = @_;
    ... # the above code
}

答案 1 :(得分:2)

以下是使此脚本有效所需的最小修改:

  1. fib()中,如果$rec为零,则在if($rec == '0')之后,它会继续测试$rec是否等于'1',因为$rec为'0',fib()将运行$f=fib($rec-1)+fib($rec-2);,并且您有无限循环。

    因此,if($rec == '1')应为elsif($rec == '1')

  2. 默认情况下,所有Perl变量都是全局变量,但在fib()的递归实现中,变量$rec应该是本地变量或私有变量,因为在

    $f=fib($rec-1)+fib($rec-2);
    

    $rec返回后,fib($rec-1)的值不应更改。

    因此,$rec=@_[0];应为my $rec=@_[0];。当然,它实际应该是my $rec = $_[0];my $rec = shift;

答案 2 :(得分:2)

除了在一个地方用elsif替换else之外,还要将$ rec作为局部变量:

sub fib
{
    my $rec=@_[0];

    print"In the subroutine rec is :".$rec."\n";
    if($rec == '0')
    {
        $f='0';
    }
    elsif($rec == '1')
    {
        $f='1';
    }
    else
    {
        $f=fib($rec-1)+fib($rec-2);
    }

    return $f;
}