您的位置:首页 > 其它

Linq递归用法(摘录)

2011-11-29 16:28 148 查看
.net framework 3.5 有了Linq使得对委托有了更多的支持,下面让我们来看几个有趣的示例.通常情况下,我们实现一个递归算法要写

一个函数,同时还有调用的几行代码.

  现在来看使用Linq的如何实现简洁的代码,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NUnit.Framework;

namespace WindowsFormsApplication1
{
/// <summary>
/// TestRecursionWithLINQ
/// </summary>
/// <remark>Author : PetterLiu 2009-03-29 11:28 http://wintersun.cnblogs.com/ </remark>
[TestFixture]
public class TestRecursionWithLINQ
{

/// <summary>
/// Factorials this instance.
/// </summary>
/// <remark>Author : PetterLiu 2009-03-29 11:28 http://wintersun.cnblogs.com/ </remark>
[Test]
public void Factorial()
{
Func<int, int> fib = null;
fib = n => (n == 1) ? 1 : fib(n - 1) * n;
Console.WriteLine(fib(5));
}

/// <summary>
/// Fibonaccis this instance.
/// </summary>
/// <remark>Author : PetterLiu 2009-03-29 11:28 http://wintersun.cnblogs.com/ </remark>
[Test]
public void Fibonacci()
{
Func<int, int> fib = null;
fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
Console.WriteLine(fib(6));
}

/// <summary>
/// Recursions the get files.
/// </summary>
/// <remark>Author : PetterLiu 2009-03-29 11:27 http://wintersun.cnblogs.com/ </remark>
[Test]
public void RecursionGetFiles()
{
var RecGetFiles =
Functional.Y<string, IEnumerable<string>>
(f => d => Directory.GetFiles(d).Concat(Directory.GetDirectories(d).SelectMany(f)));

foreach (var f in RecGetFiles(Directory.GetCurrentDirectory()))
Console.WriteLine(f);

}

/// <summary>
/// Factorial2s this instance.
/// </summary>
/// <remark>Author : PetterLiu 2009-03-29 11:28 http://wintersun.cnblogs.com/ </remark>
[Test]
public void Factorial2()
{
var dd = Functional.Y<int, int>(h => m => (m == 1) ? 1 : h(m - 1) * m);
Console.WriteLine(dd(5));
}
}

/// <summary>
/// Functional
/// </summary>
/// <remark>Author : Wes Dyer</remark>
public class Functional
{
/// <summary>
///delegate Func<A, R>
/// </summary>
private delegate Func<A, R> Recursive<A, R>(Recursive<A, R> r);
/// <summary>
/// Ys the specified f.
/// </summary>
/// <typeparam name="A"></typeparam>
/// <typeparam name="R"></typeparam>
/// <param name="f">The f.</param>
/// <returns></returns>
public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
{
Recursive<A, R> rec = r => a => f(r(r))(a);
return rec(rec);
}
}
}

Factorial是阶乘,接着是Fibonacci数列.之后把这个定义为一个名叫Funcional类,其中包含一个static方法.Factorial2使用这个类

再实现阶乘,是不是简单的多.接着是RecursionGetFiles一个实际的应用,递归遍历文件夹取得文件名列表.像树型结构算法都可以用

它来实现,是不是很有趣?

其中几个关键方法可以参考:
Func<(Of <(T, TResult>)>) 委托
封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。
Enumerable.SelectMany<(Of <(TSource, TResult>)>) 方法 (IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, IEnumerable<

(Of <(TResult>)>)>)>))
将序列的每个元素投影到 IEnumerable<(Of <(T>)>) 并将结果序列合并为一个序列。
Enumerable.Concat<(Of <(TSource>)>) 方法
连接两个序列。

Action<int, int, int> Fibonacci_A = (firstNum, secondNum, boundNum) =>
{
int exchangeNum = firstNum + secondNum;
firstNum = secondNum;
secondNum = exchangeNum ;

if (secondNum > boundNum)
{
return;
}
else
{
Console.WriteLine(exchangeNum );
MethodBase.GetCurrentMethod().Invoke(null, new object[] { firstNum, secondNum ,boundNum});
}
};

Fibonacci_A(0,1,200);
Func<int,int> Fibonacci_B = n =>
{
if ((n == 0) || (n == 1))
{
return 1;
}
return (Convert.ToInt32(MethodBase.GetCurrentMethod().Invoke(null, new object[] { n - 2 }))
+Convert.ToInt32(MethodBase.GetCurrentMethod().Invoke(null, new object[] { n - 1 })));
};

for (int i = 0; i < 10; i++)
{
Console.WriteLine(Fibonacci_B(i));
}为了实现委托自身的递归调用两个函数都通过反射来实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: