2017-09-14 29 views
-1

我想寫一個簡單的遞歸,用三次方法替換一個方法,並在完成後取回該函數運行的次數。在C#中這種遞歸有什麼問題?

我執行一個調用方法,它通過委託通過參數給出另一個方法,並打印一個簡單的消息三次。

using System; 
using System.Windows.Forms; 

namespace WindowsFormsApplication2 
{ 
    public delegate void funct(string msg); 

    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     public static void funct(string msg) 
     { 
      MessageBox.Show(msg); 
     } 

     public static int caller(funct f, string msg, int max, int count = 0) 
     { 
      if (count < max) 
      { 
       funct(msg); 
       caller(f, msg, max, ++count); 
      } 

      return count; 

     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      int a = caller(funct, "LOL", 3); 
      //should return value 3, but returned with value 1 

     } 
    } 
} 

的返回值永遠是錯的,因爲我回到1,而不是3

+1

只是把裁判詮釋計數 – MistyK

+0

返回調用者(F,味精,MAX ++數); ...發生了什麼事是它通過第一次遞歸,並返回到調用函數..返回它自己,所以它不會達到第一個返回,直到它超過最大值 – Aaron

回答

3

這是因爲你不傳回計數的遞歸鏈的價值。

public static int caller(funct f, string msg, int max, int count = 0) 
{ 
    if (count < max) 
    { 
     fugg(msg); 
     return caller(f, msg, max, ++count); 
    } 

    return count; 
} 
1

記住,你不能改變的count值在每次調用函數caller。因此,每次調用該函數時,都會返回當前值count,該值在執行結束時僅爲count加1。在caller的第一個呼叫中,計數值從零變爲1,隨後的遞歸調用caller不會再影響count的值。

也許你應該重寫caller這樣:

public static int caller(funct f, string msg, int max, int count = 0) 
    { 
     if (count < max) 
     { 
      funct(msg); 
      count = caller(f, msg, max, count + 1); 
     } 

     return count; 

    } 
0

看看你的籌碼是如何工作的:

Level 1: 
Count gets initialized as 0; 
Msgbox shows 
Calls itself 
    Level 2: 
    Count gets passed in as 1; 
    Msgbox shows 
    Calls itself 
     Level 3 
     Count gets passed in as 2; 
     Msgbox shows 
     Calls itself 
      Level 4 
      Count gets passed in as 3; 
      Count is too high; 
      returns 3; 
     Returns count (for its scope), which is 3 
    Returns count (for its scope), which is 2 
Returns count (for its scope), which is 1. 

你必須修復它的兩種簡單的方法。一個是改變變量,以便通過參考。但說實話,我更喜歡剛剛返回函數的retVal的備份鏈,就像這樣:

public static int caller(funct f, string msg, int max, int count = 0) 
    { 
     if (count < max) 
     { 
      funct(msg); 
      return caller(f, msg, max, ++count); 
     } 

     return count; 

    } 
1

您傳遞的count到recursve調用caller值。這是按值傳遞,因此即使在遞歸調用中更改count的值,也不會傳回更新的值。你只需要你回到它之前更新呼叫者計數的值:

public static int caller(funct f, string msg, int max, int count = 0) 
    { 
     if (count < max) 
     { 
      funct(msg); 
      count = caller(f, msg, max, ++count); 
     } 

     return count; 
    }