C# 递归实验

C# 递归实验,c#,java,.net,algorithm,recursion,C#,Java,.net,Algorithm,Recursion,我正在尝试递归,以便掌握这个概念。它与语言无关,因此同样的概念适用于C#和Java 我有一个TreeView,它有许多节点。我希望遍历每个节点,并计算满足特定条件的节点。如果在任何时候不满足条件,我希望算法最终返回-1 每个 TreVIEWiMe>/Cult>只考虑有标签名为“条件”(总共有3种类型的TeeVIEWWITION--我只考虑“条件”)。 一旦发现TreeViewItem是“条件”类型,我想检查它是否满足某个条件。正如我前面提到的,即使只有一个TreeViewItem不满足条件,我希

我正在尝试递归,以便掌握这个概念。它与语言无关,因此同样的概念适用于C#和Java

我有一个
TreeView
,它有许多节点。我希望遍历每个节点,并计算满足特定条件的节点。如果在任何时候不满足条件,我希望算法最终返回
-1

每个<代码> TreVIEWiMe>/Cult>只考虑有<代码>标签<代码>名为“条件”(总共有3种类型的TeeVIEWWITION--我只考虑“条件”)。

一旦发现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,而不是有效条件的数量。

您应该
返回conditionCount仅在函数末尾。只有
返回-1必须在函数的中间。

< p>使用< /p>
return conditionCount++;
这是坏习惯。有充分的理由。这里发生的是 a) return conditionCount(设置为零) b) 增量条件计数

b永远不会在return语句之后发生,因此总是将0传递给下一个递归步骤

你可以用

return ++conditionCount;
还是更好

conditionCount++;
return conditionCount;

return
立即停止整个函数并返回一个值。那不是你想要的。您希望累积值并在完成后返回总和。

这不是一个简单的递归,因为您必须同时处理错误条件和正常条件。如果没有错误条件,并且只需要计算条件节点的数量,则可以编写:

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

我认为可以通过使用异常简化代码。您要做的是在条件失败时抛出一个异常,然后可以在另一个开始递归的函数中捕获该异常。这将自动展开堆栈并中止计算。然后,捕获异常的函数可以返回您希望它返回的任何内容


除此之外,您在递归中需要做的就是为每个传递的条件累积1。

此代码不能同时是
C
Java
。这肯定不是Java。因为我还在学习,你介意解释一下为什么吗?我似乎无法理解这个概念。我会尝试你的建议,但如果你能解释我为什么要这么做,那将非常有帮助:)这也是我最初的想法,但如果至少有一个项目不满足条件,他想停止,所以可以中止。不过,我已经试着像你建议的那样修改它(虽然它确实返回了正确的计数),当它应该返回-1时,它有时返回0。请查看for each语句。在编写时,如果其中一个子项的计数为-1,则会将计数设置为-1。删除你加起来的数字直到那个孩子。另外,你的编辑现在使这里的所有答案与问题无关。那么,是否可以恢复编辑并添加新问题@多特内特似乎成功了!非常感谢你的帮助:)你能解释一下我做错了什么吗?毕竟这是一个学习练习:)@DotNET:在代码中,如果一个孩子的conditionCount为-1,则将conditionCount设置为-1,然后继续检查其他孩子。如果剩余的子项中有任何一个具有有效的conditionCount,则将其添加到conditionCount中,然后将丢失-1。如果一个孩子有一个-1条件计数,那么你应该立即返回它。@Boris怎么会这样?他返回-1,如果其中任何一个孩子产生-1,他就不会继续和其他孩子一起学习。@Phantom:嗯,他过去是这样,在回滚之前:)啊,我明白了,我只看过第1次修订版。