我在编写递归算法时遇到了一些问题。
我有一个影响其他项目的项目。 每个受影响的项目可能会影响其他项目......等。 我可以写一些有限的步骤:
var tempAffected = new List<Item>();
foreach(var item2 in item1.affectedItems)
{
if(item2.affectedItems > 0)
{
foreach(var item3 in item2.affectedItems)
{
if(item3.affectedItems > 0)
{
...
tempAffected.AddRange(item3.affectedItems)
tempAffected.Add(item3);
}
else
tempAffected.AddItem(item3);
}
}
else
tempAffected.AddItem(item2);
}
但我想要一些递归的东西。 任何帮助将不胜感激。
在我的代码中进行了一些修改后,最终代码看起来像这样。
var tempAffected = new List<HSGameItem>();
var stack = new Stack<HSGameItem>(affected);
Func<HSGameItem, List<HSGameItem>> affectedForItem = item => {
if (item.booster.accounted)
return new List<HSGameItem> ();
item.booster.accounted = true;
return item.booster.affected;
};
while(stack.Count > 0)
{
var childrenParent = stack.Pop();
foreach (var child in affectedForItem(childrenParent))
{
tempAffected.AddUnique(child);
stack.Push(child);
}
}
tempAffected.ForEach(x => x.state.Matched(mType, length));
我必须将我已经受影响的每件物品标记为&#34;记帐&#34;确保我不会再检查它。
答案 0 :(得分:1)
所以基本上你想把所有受影响的项目收集到一个名为TempAffected的临时列表中,对吗?
然后你可以这样做:
public List<Item> tempAffected = new List<Item>();
AddAffectedToDerived(item1, tempAffected);
private AddAffectedToDerived(Item root, List<Item> derived)
{
if (root.AffectedItems != null)
{
foreach(Item itemX in root.AffectedItems)
{
AddAffectedToDerived(itemX);
}
}
derived.Add(root);
}
这应该适合你。
请注意,如果您的数据结构非常大,您可能希望使用迭代方法而不是递归方式,因为存在堆栈溢出的风险。
答案 1 :(得分:1)
恕我直言,最简单的实现可能看起来像这样:
IEnumerable<Item> GetAffectedItems(Item item)
{
foreach (Item affectedItem in item.affectedItems)
{
foreach (Item subItem in GetAffectedItems(affectedItem))
{
yield return subItem;
}
}
yield return item;
}
那就是说,注意上面会实例化大量的迭代器(但至少比创建大量数据本身更好!)。编写起来很简单,但可能不如枚举所有受影响项目的其他机制那样高效。
作为一个例子,另一种方法是在你递归时建立一个List<Item>
(更像你原来的例子):
List<Item> GetAffectedItems(Item item)
{
List<Item> list = new List<Item>();
GetAffectedItems(item, list);
return list;
}
void GetAffectedItems(Item item, List<Item> list)
{
foreach (Item affectedItem in item.affectedItems)
{
GetAffectedItems(affectedItem, list);
}
list.Add(item);
}