我正在尝试递归以便掌握这个概念。它与语言无关,因此同样的概念适用于C#和Java。
我有一个TreeView
,它有许多节点。我想遍历每个节点并计算满足某个条件的节点。如果在任何时候条件不满足,我希望算法最终返回-1
。
每个TreeViewItem
只有在Tag
名为“条件”时才会被考虑(总共有3种类型的TreeViewItems - 我只会考虑“条件”类型)。
一旦发现TreeViewItem属于“条件”类型,我想检查它是否满足某个条件。正如我之前提到的,即使只有一个TreeViewItem不满足条件,我希望算法最终返回-1。
如果算法没有返回-1,我希望它返回它找到的有效条件的数量 - 即每次条件成功通过时都会递增一个整数,并在最后计数返回端。
这是我到目前为止所尝试的:
private int CountConditions(TreeViewItem item)
{
int conditionCount = 0;
foreach (TreeViewItem child in item.Items)
{
int previousCount = CountConditions(child);
if (previousCount == -1)
{
return -1;
}
else
{
return conditionCount += previousCount;
}
}
if (item.Tag.Equals("Condition"))
{
if (/*Condition is not satisfied*/)
{
return -1;
}
else
{
return conditionCount++;
}
}
else
{
return conditionCount;
}
}
如果不满足条件,我当前的算法会返回-1,但是如果条件满足则只返回0,而不是有效条件的数量。
答案 0 :(得分:2)
你使用
return conditionCount++;
这是不好的做法。有充分理由。这里发生的是 a)返回conditionCount(你设置为零) b)增加conditionCount
b在return语句之后永远不会发生,所以你总是将0传递给你的下一个递归步骤。
你可以使用
return ++conditionCount;
或更好的
conditionCount++;
return conditionCount;
答案 1 :(得分:1)
这不是一个简单的递归,因为你必须同时处理错误条件和正常条件。如果您没有错误条件,并且只需要计算条件节点的数量,您可以写:
private int CountConditions(TreeViewItem item)
{
int currentCondition = CalculateCondition(item)
int childCounts = 0;
foreach (TreeViewItem child in item.Items)
{
int childCount = CountConditions(child);
childCounts += childCount;
}
return currentCondition + conditionCounts
}
private int CalculateCondition(TreeViewItem item)
{
if (item.Tag.Equals("Condition"))
return 1;
else
return 0;
}
但是要处理错误,您必须对错误条件进行两次检查,一次针对当前节点,一次针对子节点,如果遇到这种情况,则立即返回:
int error = -1
private int CountConditions(TreeViewItem item)
{
int currentCondition = CalculateCondition(item)
if (currentCondition == error) // new
return error; // new
int childCounts = 0;
foreach (TreeViewItem child in item.Items)
{
int childCount = CountConditions(child);
if (childCount == error) // new
return error; // new
childCounts += childCount;
}
return currentCondition + conditionCounts
}
private int CalculateCondition(TreeViewItem item)
{
if (item.Tag.Equals("Condition"))
if (((item.Header as StackPanel).Children[2] as TextBox).Text.Equals("")) // new
return error; // new
else // new
return 1;
else
return 0;
}
答案 2 :(得分:0)
您应该return conditionCount;
仅在该功能的结束。只有return -1;
必须位于函数的中间。
答案 3 :(得分:0)
return
立即停止整个函数并返回一个值。那不是你想要的。您希望累积值并在完成后返回总和。
答案 4 :(得分:0)
我认为您可以通过使用异常来简化代码。你所做的是在条件失败时抛出异常,然后你可以在另一个开始递归的函数中捕获它。这将自动展开堆栈并中止计算。捕获异常的函数可以返回您想要的任何内容。
除此之外,你在递归时所要做的就是为每个传递条件积累1。