2014-02-28 124 views
0

您好我正在嘗試使用perl執行遞歸函數的斐波那契數列。這是代碼perl中的斐波那契數列執行到無限循環

#! /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 
{ 
    [email protected]_[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; 
} 

但是,這段代碼最終以無限循環結束。任何人都可以幫我解決我犯的錯誤。

+1

對這個問題的回答指出你的代碼如何工作,但還有很多需要改進。如果您想將驗證碼批評,流行到[codereview.se。 – amon

回答

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 
} 
+0

真棒!謝謝@amon – Programmer

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)返回變化。因此,[email protected]_[0];應爲my [email protected]_[0];。當然,它實際上應該是my $rec = $_[0];my $rec = shift;

+0

我甚至試過,但我仍然因爲在你的'FIB()'面臨同樣的問題 – Programmer

+0

@Programmer也就是說,'$ rec'是全球性的,它應該是本地的。 –

2

而且在一個地方更換另外通過ELSIF,使$ REC一個局部變量:

sub fib 
{ 
    my [email protected]_[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; 
}