我有一个递归的C#应用程序,它遍历一个树,只要最后一个节点等于X,就需要维护链中所有节点的历史记录。
例如,我正在搜索下面的MATCH一词
Root
|
|-Node1
| |-Sub1
| |-MATCH
|
|-Node2
| |-Node22
| |-Node33
| | |-MATCH
| |-Node3
|
|-Node3
| |-Node88
|-MATCH
注意Node3是Node2的兄弟。我的目标是确定根与遇到MATCH的每条路径之间的父子关系。这意味着生成以下输出:
Root -> Node1 -> MATCH
Root -> Node2 -> Node33 -> MATCH
Root -> Node2 -> Node3 -> MATCH
Root -> Node3 -> MATCH
对此进行编码的正确方法是什么?
我立即看到,任何跟踪深路径或长路径的尝试都会导致大部分内存被用于跟踪没有值的路径。唯一有价值的路径是上面列出的路径,其中找到匹配
我的目标是在Azure Table或Blob存储上实现这一点...每个IO查询批量为100行,在每个级别的heiarchy中最多可查询20,000行。
我确信此前已经完成,但不知道它会被称为什么..
问题
我应该如何引用内存中的字符串以便消耗最少的RAM?
示例答案:
使用带有ref参数的结构......或......
Struct MyMemoryData
{
public string PreviousNode {get;set;}
public string NodeName {get;set;}
}
void MyRecursion(MyMemoryData searchStack, List<string> nodesToQuery)
{
foreach(var str in nodesToQuery)
{
var newToDoList = GetChildNodes(str);
searchStack.PreviousNode = searchStack.CurentNode;
searchStack.CurrentNode = str;
MyRecursion(searchStack, newToDoList);
}
}
或将ref保存到struct
Struct MyMemoryData
{
public MyMemoryData PreviousNode {get;set;} // this line was changed: Type is MyMemoryData
public string NodeName {get;set;}
}
void MyRecursion(MyMemoryData searchStack, List<string> nodesToQuery)
{
foreach(var str in nodesToQuery)
{
var newToDoList = GetChildNodes(str);
searchStack.PreviousNode = searchStack; // this line was changed: Saving the object instead of the value
searchStack.CurrentNode = str;
MyRecursion(searchStack, newToDoList);
}
}
或者只是将它们保存在这样的列表中:
void MyRecursion(List<string> searchStack, List<string> nodesToQuery)
{
foreach(var str in nodesToQuery)
{
var newToDoList = GetChildNodes(str);
searchStack.Add(str);
MyRecursion(searchStack, newToDoList);
}
}
答案 0 :(得分:0)
您打算提供多少级别?堆栈的大小应该受树的深度影响,而不是每个级别的项目数。
void MyRecursion(Stack<string> searchStack, List<string> nodesToQuery)
{
foreach(var str in nodesToQuery)
{
var newToDoList = GetChildNodes(str);
searchStack.Push(str);
MyRecursion(searchStack, newToDoList);
searchStack.Pop(); // make sure to get pop off the current once you are no longer on this level
}
}
编辑:老实说,我认为您可能想要考虑一种迭代方法。你的大部分内存将被newToDoList
存储在每个递归级别。如果你可以顺序遍历树(想想XmlReader
只是向前)并保持一个堆栈,你可能会更好。
答案 1 :(得分:0)