2013-03-16 126 views
0

我有搞清楚艱難的時間,如何從我的遞歸函數退出如何退出這個遞歸循環?

我的代碼是

public Main() 
    { 
     GetFibonacci(5,20); 
    } 

private void GetFibonacci(int StartNUmber, int LastNumber) 
    { 
     if (StartNUmber < LastNumber) 
     { 
      if (FibonacciRecursiveList.Count == 0 || FibonacciRecursiveList.Count == 1) 
      { 
       FibonacciRecursiveList.Add(StartNUmber); 
      } 
      else 
      { 
       int value = FibonacciRecursiveList[FibonacciRecursiveList.Count - 1] + FibonacciRecursiveList[FibonacciRecursiveList.Count - 2]; 
       FibonacciRecursiveList.Add(value); 
      } 
      StartNUmber++; 
      GetFibonacci(StartNUmber, LastNumber); 
     } 
     else 
     { 
      return; 
     } 
    } 

在到達外其他循環的代碼仍然運行

請幫

+0

你是否在代碼上設置了一個斷點來驗證'return'語句是否真的被達到了?我懷疑編譯器是否被破壞,並繼續循環,即使代碼說不。 – 2013-03-16 10:43:06

+0

是的,我已經做到了 – Rohit 2013-03-16 10:43:57

+0

爲什麼要遞歸地調用函數?用一個包含以前值的列表('FibonacciRecursiveList'),你實際上不需要遞歸調用。 – 2013-03-16 10:47:01

回答

3

當它到達return語句時,它不會立即返回到主函數。它必須通過遞歸調用返回15次才能恢復到主要狀態。

返回堆棧的開銷很小。只要不會太深,這種遞歸方法就沒有問題。如果你想要達到一個很大的數目,那麼你將不得不將它重新編碼爲一個循環。

+0

我想多數民衆贊成我的解決方案......但是我失去了什麼..如何我可以避免它? – Rohit 2013-03-16 10:51:52

+0

你不想避免它。所有遞歸算法都以這種方式工作。 – SteveP 2013-03-16 10:53:52

+0

@Kyle:這就是遞歸函數的工作原理。 如果你不想要它,你可以嘗試使用While循環和break來重寫你的邏輯/函數;而不是遞歸。 – 2013-03-16 10:54:37

0

GetFibbonaci返回或堆棧溢出,StackOverflowException被拋出。 (推斷這一點很簡單,因爲沒有循環,只有遞歸。)除非知道拋出異常,否則它必須返回。

0

我覺得你在FibonacciRecursiveList的下面的值上面的代碼運行OK。 但是,不知道這是否是預期的/預期的輸出。

[0] 5 int 
    [1] 6 int 
    [2] 11 int 
    [3] 17 int 
    [4] 28 int 
    [5] 45 int 
    [6] 73 int 
    [7] 118 int 
    [8] 191 int 
    [9] 309 int 
    [10] 500 int 
    [11] 809 int 
    [12] 1309 int 
    [13] 2118 int 
    [14] 3427 int 
2

您對遞歸調用的使用是錯誤的,然而,您的遞歸調用確實完成沒有問題。

我猜,你所看到的

在到達外其他循環的代碼仍然運行

是遞歸調用!當代碼達到return聲明時,該方法已被調用16次!所以return語句會讓我們回到方法被調用的地方,這是if塊的最後一行。之後,此方法調用也完成了,因此執行將返回到該函數的前一個調用,該調用恰好是第14次調用,位於同一行。這將繼續進行所有呼叫,直到執行返回到Main

您可以輕鬆實現你想要的東西沒有一個遞歸調用:

public void Main() 
{ 
    FibonacciRecursiveList = new List<int>(); 
    GetFibonacci(5,20); 
} 


private void GetFibonacci(int StartNUmber, int LastNumber) 
{ 
    while (StartNUmber < LastNumber) 
    { 
     if (FibonacciRecursiveList.Count == 0 || FibonacciRecursiveList.Count == 1) 
     { 
      FibonacciRecursiveList.Add(StartNUmber); 
     } 
     else 
     { 
      int value = FibonacciRecursiveList[FibonacciRecursiveList.Count - 1] + FibonacciRecursiveList[FibonacciRecursiveList.Count - 2]; 
      FibonacciRecursiveList.Add(value); 
     } 
     StartNUmber++; 
    } 
} 
+0

謝謝MD這是非常翔實的 – Rohit 2013-03-16 11:05:53

+0

@Kyle不客氣。 – 2013-03-16 11:08:38

0

這是我運行代碼:

using System; 
using System.Collections.Generic; 
public class Main1{ 
public Main1() 
    { 
     FibonacciRecursiveList = new List<int>(); 
     GetFibonacci(5,20); 
    } 
private List<int> FibonacciRecursiveList; 
private void GetFibonacci(int StartNUmber, int LastNumber) 
    { 
     if (StartNUmber < LastNumber) 
     { 
      if (FibonacciRecursiveList.Count == 0 || FibonacciRecursiveList.Count == 1) 
      { 
       FibonacciRecursiveList.Add(StartNUmber); 
      } 
      else 
      { 
       int value = FibonacciRecursiveList[FibonacciRecursiveList.Count - 1] + FibonacciRecursiveList 

[FibonacciRecursiveList.Count - 2]; 
       FibonacciRecursiveList.Add(value); 
      } 
      StartNUmber++; 
      GetFibonacci(StartNUmber, LastNumber); 
     } 
     else 
     { 
      return; 
     } 
    } 

public static void Main(string[] args) { 

    Main1 main = new Main1(); 
    foreach(int a in main.FibonacciRecursiveList){ 
     Console.WriteLine(a); 
    } 
} 
} 

沒有計算器或無限循環!

輸出:

5 
6 
11 
17 
28 
45 
73 
118 
191 
309 
500 
809 
1309 
2118 
3427 
0

在到達外其他循環的代碼仍然運行?

我認爲實際的問題是StartNUmber值不被引用更新BACK遞歸,用於該用途的通

真正的代碼變得

List<int> FibonacciRecursiveList = new List<int>(); 
    private void GetFibonacci(ref int StartNUmber, ref int LastNumber) 
{ 
    if (StartNUmber < LastNumber) 
    { 
     if (FibonacciRecursiveList.Count == 0 || FibonacciRecursiveList.Count == 1) 
     { 
      FibonacciRecursiveList.Add(StartNUmber); 
     } 
     else 
     { 
      int value = FibonacciRecursiveList[FibonacciRecursiveList.Count - 1] + FibonacciRecursiveList[FibonacciRecursiveList.Count - 2]; 
      FibonacciRecursiveList.Add(value); 
     } 
     StartNUmber++; 
     GetFibonacci(ref StartNUmber, ref LastNumber); 
    } 
    else 
    { 
     return; 
    } 
} 

然後調用

int T = 1; 
    int T2 = 12; 
    GetFibonacci(ref T, ref T2); 

設我知道我是否正確?