2009-09-03 9 views
0

C#で再帰関数内の成功ケースの数を計算しようとしていますが、私の変数がすべての関数呼び出しで共有されていることに驚いています。再帰関数で変数が共有される

[アップデート2]奇妙より

より今回。完全なコード:この

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

をやってそう

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

リセット私にには0

[更新(私はそれが正しいかどうか分からない)いくつかの結果を提供します]

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; 
    } 

変数iをデバッグすると値1が取られますが、次の反復では0にリセットされます!

i = i + .... 

コードのその部分での問題は何ですか?の使用にもかかわらず

なしのローカル変数が全く再帰呼び出し間で共有されていないされていない、あなたが他のいくつかの設計上の問題を考慮する必要があり、あなたのforeachループの内側と後に、私はすべてのreturn文を参照してくださいいけないあなたに

+0

のように書くことができ、私はあなたがrecurisveコールを皮肉って、単純なREPROを作成し、すべてのリスト、ツリーとLINQものを取り除くべきだと思います。 cut'n'pastedできる完全なReproを作り出すことができますか? – AnthonyWJones

+0

私は元の(編集)質問を見ましたが、ここでコード全体を尋ねました。私はコードを間違えたかもしれないからです! – 0xFF

答えて

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 right!それは魔法でしたが、実際にはループを終了することなく機能を終了しましたが、続行するとすべての要素をスキャンします!ありがとうございました – 0xFF

3

をありがとう、あなたは完全なコードを投稿することができます。

私は現在のメソッドの値を常に監視しますが、デバッグは再帰関数では良くなく、少し理解しにくいので、コールスタックでコントロールを下に移動して、実際の値を実際に観察する必要があります現在の関数の呼び出し元。

実際のデバッグに役立つノードレベルのTraceまたはログファイルを出力するようアドバイスします。

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

okフルコードが更新されました – 0xFF

+0

デバッグは常に現在のメソッドのiのみを表示するので、値を出力するにはTraceステートメントを実行してください。以前の呼び出し元の値は観測されません。 –

+0

そうですよ!結局のところ、最後に、私はすべての呼び出しの合計を持っている必要があります!それは常に0です – 0xFF

1

ローカル変数が共有されていない。..続くようTRACEステートメントを使用してください。 あなたが見ているもの(0にリセット)は、(再帰的に)関数validTreesFunと呼ばれるiの値です(iは関数の最初に0に設定されます)。

あなたのコードを見てみると、someTestHereにバグがある可能性があります。これが真実でない場合、私は外側のスコープに0を残します。それ以外の場合は、真のテストごとに1ずつ増分する必要があります。

+0

デバッグ時にテストはtrueを返しますが、次の繰り返しですぐに0にリセットされます。合計が返されます – 0xFF

-1

デバッグモードになっているときは、実際にはiがコール用にリセットされていても、呼び出し元の希望の値にとどまっていることがわかります。ある

validTreesFun --i = 0この1のために、この1

validTreesFun --i = xについて、しかし、あなたは呼び出しスタックをトロウ行っていない場合は、0が表示されます、:例えば、スタックスタックの先頭