我试图在递归调用中跟踪父母,并标记正确的亲子关系。

有4个类(不要介意名称,这是示例的伪代码):



童块
最后
儿童一次性


所有3个子类都继承自一个抽象类:Child。

根显然是拥有所有孩子的最上等人,根没有父母。但是,从某种意义上讲,其他类也没有。根有孩子,每个孩子都有孩子。但反之亦然。 ChildBlock(以及所有其他)没有存储任何父项,仅存储了一个子项列表。看到代码:

internal abstract class Child
{
    public string name;
    public List<Child> children;

    public Child()
    {
        name = "Child";
        children = new List<Child>();
    }

    public virtual void AddChild(Child child)
    {
        children.Add(child);
    }
}

internal class ChildFinally : Child
{
    public ChildFinally(string level)
    {
        name = level + ": ChildFinally";
        children = new List<Child>();
    }
}


假设您有一个带有一个孩子的根(级别1):ChildBlock(级别2)。 ChildBlock本身有两个孩子:ChildFinally(级别3)和ChildBlock(级别3)。 ChildFinally(级别3)和ChildBlock(级别3)都有一个孩子:ChildDisposable(级别4)。

因此,以一种分层的方式(我为它们着色以更准确地显示级别):


我要达到的目的是:我想知道ChildDisposable(level 4)是否在其上方的任何级别都有ChildFinally类型的父母。

这里的问题是ChildDisposable不知道它的父级,但是父级(通过子级列表)知道他的子级。

现在,我在递归调用中遍历所有子级列表:

private static void DisplayChildren(Child child)
{
    foreach (Child c in child.children)
    {
        Console.WriteLine(c.name);
        DisplayChildren(c);
    }
}


该递归调用必须保持这种方式。另外,我不能让孩子知道他们的父母。

我有什么方法可以跟踪ChildDisposable类型的子项是否具有ChildFinally类型的父项(在任何级别)?

编辑:如果需要,我可以提供完整的(可复制的)伪代码。

最佳答案

根据我们所知道的很难说,但我想我可以猜得出一点。

无论如何,如果我是对的话,您会以某种方式走树,所以我的建议是在走树时记住某种路径信息(应该是微不足道的-这只是步行者的另一个论点)-您可以轻松地存储像最后一个孩子这样的事情

那将是您的示例:

private static void DisplayChildren(Child child)
{
    DisplayChildren(child, new []{child});
}

private static void DisplayChildren(Child child, Child[] path)
{
    foreach (Child c in child.children)
    {
        Console.WriteLine(c.name);
        var newPath = new List<Child>(path);
        newPath.Add(c);
        DisplayChildren(c, newPath.ToArray());
    }
}


当然,我不知道真正需要什么,因此此示例仅向您提供当前孩子(包括它)的路径-应该很容易找到您所需要的:

static bool HasFinalParent(Child[] path)
{
   return path.Any(c => c is ChildFinally);
}


或更简单(仅记住父母,如果有的话):

private static void DisplayChildren(Child child)
{
    DisplayChildren(child, null);
}

private static void DisplayChildren(Child child, ChildFinally lastFinalParent)
{
    if (child is ChildFinally)
       lastFinalParent = (ChildFinally)child;

    foreach (Child c in child.children)
    {
        Console.WriteLine(c.name);
        DisplayChildren(c, lastFinalParent);
    }
}

09-28 08:25