我正在尝试计算C#中递归函数中的成功案例数,但我对所有函数调用之间共享变量的事实感到惊讶!
[更新2]
这次不仅仅是奇怪。这样做
i = i + validTreesFun(tree.Nodes, newWords.ToList()) ;
将i重置为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 :(得分:5)
if (validWords.Count() == 0)
return 0;
应该是
if (validWords.Count() == 0)
continue;
另外,一般来说,我个人认为一次只能将一个元素发送到递归函数更好。
public static int validTreesFun(Tree<char> node, List<string> words)
这样你就不会像上面那样得到同样的错误。最后,一个小调。
w => w.ToCharArray()[0] == tree.Root
可以写成
w => w[0] = tree.Root
答案 1 :(得分:3)
在递归调用之间没有共享任何局部变量,你应该考虑一些其他的设计问题,在你的foreach循环内部和之后,我没有看到任何返回语句,你可以发布完整的代码。
好的,在调试中你总会观察到我当前方法的值,调试在递归函数中不好,它有点难以理解,你必须在Call Stack中向下移动你的控件以便实际观察早期调用者的值当前的功能。
我建议您输出跟踪或日志文件的节点级别,这将有助于您进行实际调试。
请使用TRACE声明如下..
Trace.WriteLine(string.Format("{0},{1}",tree.Name,i));
答案 2 :(得分:1)
未共享本地变量。
你所看到的(重置为0)是(递归)调用函数validTreesFun
中i的值(我在函数开始时将其设置为0)。
只是查看你的代码,我认为可能的错误可能在someTestHere
- 如果那是真的,那么我将在外部范围内保持0。否则,每次真实测试应该增加1。
答案 3 :(得分:-1)
当您处于调试模式时,您确实看到i已重置为该呼叫,但保持为呼叫者所需的值。例如,堆栈:
validTreesFun --i = 0 for this one
validTreesFun --i = x这个,但如果你不去调用堆栈,你会看到0,这是堆栈顶部的好值