【问题标题】:condition in recursion - best practise递归条件 - 最佳实践
【发布时间】:2011-02-13 22:10:27
【问题描述】:

打破循环的最佳做法是什么? 我的想法是:

Child Find(Parent parent, object criteria)
{
    Child child = null;

    foreach(Child wannabe in parent.Childs)
    {
        if (wannabe.Match(criteria))
        {
            child = wannabe;
        }
        else
        {
            child = Find(wannabe, criteria);
        }

        if (child != null) break;
    }

    return child;
}

Child Find(Parent parent, object criteria)
{
    Child child = null;
    var conditionator = from c in parent.Childs where child != null select c;

    foreach(Child wannabe in conditionator)
    {
        if (wannabe.Match(criteria))
        {
            child = wannabe;
        }
        else
        {
            child = Find(wannabe, criteria);
        }
    }

    return child;
}

Child Find(Parent parent, object criteria)
{
    Child child = null;
    var enumerator = parent.Childs.GetEnumerator();

    while(child != null && enumerator.MoveNext())
    {
        if (enumerator.Current.Match(criteria))
        {
            child = wannabe;
        }
        else
        {
            child = Find(wannabe, criteria);
        }
    }

    return child;
}

你怎么看,有更好的主意吗? 我正在寻找最好的解决方案:D

【问题讨论】:

  • 这需要在哪个版本的 .NET/C# 中工作?
  • 您在所有示例中都递归调用 Find,这是否意味着 Child 继承自 Parent?
  • 它只是伪代码 :) 让我们想象一个接口 IFinder :)

标签: c# .net recursion conditional


【解决方案1】:

Linq 可能更简洁,但可能更难理解!

    Child Find(Parent parent, object criteria)
    {
        return parent.Childs.Select(        // Loop through the children looking for those that match the following criteria
            c => c.Match(criteria)          // Does this child match the criteria?
                ? c                         // If so, just return this child
                : this.Find(c, criteria)    // If not, try to find it in this child's children
        ).FirstOrDefault();                 // We're only interested in the first child that matches the criteria or null if none found
    }

【讨论】:

  • @mo 哈哈!您不喜欢声称难以调试的多个返回语句,但这可以接受吗?尝试使用调试器单步执行,看看几个月后当代码在您的脑海中不新鲜时您会更喜欢哪个。 :-)
  • 这确实是一个很酷的解决方案。但是我团队中的一些开发人员永远不会理解它 :) 对他们来说很难理解。
  • 它只有一个回报:)。调试问题依然存在
  • 这很难理解(对于 unexp.devs)。但对于一个简单的递归搜索,它会完成这项工作。 (它不可调试):)
  • 这是否真的在第一次正面命中后终止?
【解决方案2】:

您无需自己处理IEnumerator,因此选项3 已失效。

选项 2 不起作用。无论找到匹配项,它都会继续,如果最后一个子项不匹配并且其子项不包含匹配项,则即使之前存在匹配项,结果也会为 null

假设您反对多个 return 语句,选项 1 似乎最干净。

【讨论】:

  • @mo:选项 2 仍然存在问题。
  • 选项 1 有一个问题,即使它已经找到了一个匹配项,它也会继续递归搜索其他子项中的匹配项。
  • @Ants:不,不会的;选项 2 会这样做,而不是选项 1。
  • 我没有看到我的错@2.the linq-expr。如果 child != null 则中断。所以 foreach 会破裂。我瞎了!
  • 我发布后有人进行了编辑。那“如果(孩子!= null)打破;”选项 1 中最初没有行。“break”曾经在成功子句中。
猜你喜欢
  • 2014-12-20
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
  • 2021-05-01
相关资源
最近更新 更多