.net3.5下使用LINQ递归算法实现简洁代码

  .net framework 3.5 有了Linq使得对委托有了更多的支持,下面让我们来看几个有趣的示例.通常情况下,我们实现一个递归算法要写一个函数,同时还有调用的几行代码.

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

    1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.IO;
    6 using NUnit.Framework;
    7 
    8 namespace WindowsFormsApplication1
    9 {
   10     /// <summary>
   11     /// TestRecursionWithLINQ
   12     /// </summary>
   13     /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com </remark>
   14     [TestFixture]
   15     public class TestRecursionWithLINQ
   16     {
   17 
   18         /// <summary>
   19         /// Factorials this instance.
   20         /// </summary>
   21         /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com </remark>
   22         [Test]
   23         public void Factorial()
   24         {
   25             Func<int, int> fib = null;
   26             fib = n => (n == 1) ? 1 : fib(n - 1) * n;
   27             Console.WriteLine(fib(5));
   28         }
   29 
   30         /// <summary>
   31         /// Fibonaccis this instance.
   32         /// </summary>
   33         /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com </remark>
   34         [Test]
   35         public void Fibonacci()
   36         {
   37             Func<int, int> fib = null;
   38             fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
   39             Console.WriteLine(fib(6));
   40         }
   41 
   42 
   43         /// <summary>
   44         /// Recursions the get files.
   45         /// </summary>
   46         /// <remark>Author : PetterLiu 2009-03-29 11:27  http://wintersun.cnblogs.com </remark>
   47         [Test]
   48         public void RecursionGetFiles()
   49         {
   50             var RecGetFiles =
   51                 Functional.Y<string, IEnumerable<string>>
   52                 (f => d => Directory.GetFiles(d).Concat(Directory.GetDirectories(d).SelectMany(f)));
   53 
   54             foreach (var f in RecGetFiles(Directory.GetCurrentDirectory()))
   55                 Console.WriteLine(f);
   56 
   57         }
   58 
   59         /// <summary>
   60         /// Factorial2s this instance.
   61         /// </summary>
   62         /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com </remark>
   63         [Test]
   64         public void Factorial2()
   65         {
   66             var dd = Functional.Y<int, int>(h => m => (m == 1) ? 1 : h(m - 1) * m);
   67             Console.WriteLine(dd(5));
   68         }
   69     }
   70 
   71     /// <summary>
   72     /// Functional
   73     /// </summary>
   74     /// <remark>Author : Wes Dyer</remark>
   75     public class Functional
   76     {
   77         /// <summary>
   78         ///delegate  Func<A, R>
   79         /// </summary>
   80         private delegate Func<A, R> Recursive<A, R>(Recursive<A, R> r);
   81         /// <summary>
   82         /// Ys the specified f.
   83         /// </summary>
   84         /// <typeparam name="A"></typeparam>
   85         /// <typeparam name="R"></typeparam>
   86         /// <param name="f">The f.</param>
   87         /// <returns></returns>
   88         public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
   89         {
   90             Recursive<A, R> rec = r => a => f(r(r))(a);
   91             return rec(rec);
   92         }
   93     }
   94 }

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>)>) 方法
连接两个序列。

Author: Petter Liu    http://wintersun.cnblogs.com

你可能感兴趣的:(.net)