我试图在递归调用中跟踪父母,并标记正确的亲子关系。
有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);
}
}