2009-09-03 89 views
0

我試圖計算C#中遞歸函數內成功案例的數量,但我驚訝於我的變量在所有函數調用之間共享!在遞歸函數中共享變量

[更新2]

比怪此時更多。這樣做

i = i + validTreesFun(tree.Nodes, newWords.ToList()) ; 

重置我到0

這樣

i = validTreesFun(tree.Nodes, newWords.ToList()) + i ; 

給出了一些成績(我不知道這是否是正確的)

[更新:全碼]

public static int validTreesFun(List<Tree<char>> nodes, List<string> words) 
    { 
     int i = 0; 
     if (nodes == null && (words == null || words.Count == 0 || (words.Count == 1 && words.First() == ""))) 
      return 1; 
     else 
      if (nodes == null) 
       return 0; 

     foreach (Tree<char> tree in nodes) 
     { 
      var validWords = words.Where(w => w.ToCharArray()[0] == tree.Root) 
       .Select(w => w); 
      if (validWords.Count() == 0) 
       return 0; 
      else 
      { 
       var newWords = validWords.Select(w => join(w.ToCharArray().Skip(1).ToArray())); 
       i += validTreesFun(tree.Nodes, newWords.ToList()); 
      } 
     } 
     return i; 
    } 

調試變量時,我取值1,但它在下一次迭代中重置爲0! 儘管使用了

i = i + .... 

什麼是這段代碼的問題?

謝謝

+0

我想你應該創建一個簡單的攝製嘲笑的recurisve電話並刪除所有列表,樹和LINQ的東西。你能製作一個完整的Repro,可以切割出來嗎? – AnthonyWJones 2009-09-03 11:27:09

+0

我做過了,看到原始(編輯)問題,但這裏的人問完整的代碼,因爲我可能在代碼上犯了一些錯誤! – 0xFF 2009-09-03 11:29:51

回答

5
if (validWords.Count() == 0) 
    return 0; 

應該

if (validWords.Count() == 0) 
    continue; 

而且,在一般情況下,我個人認爲這是更好看在同一時間中的一個元素只發送給一個遞歸福nction。

public static int validTreesFun(Tree<char> node, List<string> words) 

這樣你就不會像上面那樣得到同樣的錯誤。最後,小調。

w => w.ToCharArray()[0] == tree.Root 

可以寫成

w => w[0] = tree.Root 
+0

WAW!這是魔術,我沒有完成循環就退出了函數,但繼續掃描所有元素!再次感謝你 – 0xFF 2009-09-03 11:43:47

3

沒有局部變量是不是在所有的遞歸調用之間共享,你應該考慮其他的一些設計問題,內部和foreach循環後,我沒有看到任何return語句,你能發佈完整的代碼。

好的,在調試中你總是會觀察到i的當前方法的值,調試在遞歸函數中不好,它很難理解,你將不得不在調用堆棧中移動你的控件,以便實際觀察早期的值當前函數的調用者。

我建議你輸出跟蹤或日誌文件與你的節點級別,這將有助於你的實際調試。

請使用跟蹤語句如下..

Trace.WriteLine(string.Format("{0},{1}",tree.Name,i)); 
+0

ok完整代碼已更新 – 0xFF 2009-09-03 11:03:32

+0

請跟蹤語句以輸出值,因爲調試只會顯示當前方法的i,因此您將永遠無法觀察到較早的調用者值,請詳細參閱我的更新答案。 – 2009-09-03 11:12:59

+0

沒錯!但畢竟,最後,我應該有所有電話的總和!它總是0雖然 – 0xFF 2009-09-03 11:14:46

1

局部變量沒有被共享。 你所看到的(重置爲0)是我在(遞歸)調用函數validTreesFun(我在函數開始時設置爲0)中的值。

只看你的代碼,我認爲可能的錯誤可能在someTestHere - 如果這從來沒有真的,那麼我會留在外面的範圍0。否則,每次真正的測試都應該增加1。

+0

當我調試時,測試返回true,但下一次迭代立即復位爲0,它不返回總和 – 0xFF 2009-09-03 11:06:04

-1

當您處於調試模式時,您確實看到我爲該呼叫重置,但仍保持呼叫者的期望值。例如,棧:

validTreesFun --i = 0這一個

validTreesFun --i = X這一個,但如果你不去特羅調用堆棧,你會看到0,這是堆棧的頂部物有所值