C# 处理常见递归函数
我注意到在我的项目中,我们经常编写递归函数 我的问题是:有没有办法为使用递归迭代的每个层次结构创建递归函数作为泛型函数 也许我可以使用一个委托来获取递归的根和结束标志 有什么想法吗C# 处理常见递归函数,c#,recursion,hierarchy,C#,Recursion,Hierarchy,我注意到在我的项目中,我们经常编写递归函数 我的问题是:有没有办法为使用递归迭代的每个层次结构创建递归函数作为泛型函数 也许我可以使用一个委托来获取递归的根和结束标志 有什么想法吗 谢谢。我不确定你的问题到底想问什么,但递归函数可以是泛型的。这是没有限制的。例如: int CountLinkedListNodes<T>(MyLinkedList<T> input) { if (input == null) return 0; return 1 + CountL
谢谢。我不确定你的问题到底想问什么,但递归函数可以是泛型的。这是没有限制的。例如:
int CountLinkedListNodes<T>(MyLinkedList<T> input) {
if (input == null) return 0;
return 1 + CountLinkedListNodes<T>(input.Next);
}
int CountLinkedListNodes(MyLinkedList输入){
if(input==null)返回0;
返回1+CountLinkedListNodes(input.Next);
}
一种更简单且通用的方法可能是缓存函数的结果,并仅在结果已知时使用“real”函数-此方法的有效性取决于递归过程中使用同一组参数的频率
如果您知道Perl,您应该查看电子书中的前4章,其中的思想是独立于语言的。听起来您的解决方案可以成功地使用Perl 您可以通过创建的来创建的特定变体
在这里完全讨论有点复杂,但这应该让你开始一些研究。基本思想是,您有一个知道如何遍历结构的类,然后您有一个知道如何处理特定节点的访问者类。您可以将树的遍历与节点的处理分开。我认为您需要的是一种以通用方式处理层次结构的方法(“通用”在英语中定义,不一定在.Net中定义)。例如,当我需要在Windows窗体中获取所有控件时,我曾经编写过以下内容:
public static IEnumerable<T> SelectManyRecursive<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> selector)
{
if (items == null)
throw new ArgumentNullException("items");
if (selector == null)
throw new ArgumentNullException("selector");
return SelectManyRecursiveInternal(items, selector);
}
private static IEnumerable<T> SelectManyRecursiveInternal<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> selector)
{
foreach (T item in items)
{
yield return item;
IEnumerable<T> subitems = selector(item);
if (subitems != null)
{
foreach (T subitem in subitems.SelectManyRecursive(selector))
yield return subitem;
}
}
}
// sample use, get Text from some TextBoxes in the form
var strings = form.Controls
.SelectManyRecursive(c => c.Controls) // all controls
.OfType<TextBox>() // filter by type
.Where(c => c.Text.StartWith("P")) // filter by text
.Select(c => c.Text);
我的问题是:有没有办法为使用递归迭代的每个层次结构创建递归函数作为泛型函数?
我可以使用一个委托来获取递归的根和结束标志吗
是-您唯一需要的是一个委托函数,它为每个元素计算子元素列表。当没有返回子函数时,函数终止
delegate IEnumerable<TNode> ChildSelector<TNode>(TNode Root);
static IEnumerable<TNode> Traverse<TNode>(this TNode Root, ChildSelector<TNode> Children) {
// Visit current node (PreOrder)
yield return Root;
// Visit children
foreach (var Child in Children(Root))
foreach (var el in Traverse(Child, Children))
yield return el;
}
你需要更具体一些。可能有一种方法可以使其泛型化,但如果没有更多信息,我们将无能为力。您希望泛型化的代码示例在这里会有很大帮助。+1.Net 2.0需要委托声明。但是,如果您的目标是.Net 3.5+,则可以简单地使用Func
delegate IEnumerable<TNode> ChildSelector<TNode>(TNode Root);
static IEnumerable<TNode> Traverse<TNode>(this TNode Root, ChildSelector<TNode> Children) {
// Visit current node (PreOrder)
yield return Root;
// Visit children
foreach (var Child in Children(Root))
foreach (var el in Traverse(Child, Children))
yield return el;
}
static void Main(string[] args) {
var Init = // Some path
var Data = Init.Traverse(Dir => Directory.GetDirectories(Dir, "*", SearchOption.TopDirectoryOnly));
foreach (var Dir in Data)
Console.WriteLine(Dir);
Console.ReadKey();
}