Linq下的函数式编程初探

接触c#又好几年了,感觉整个c#功能确实很强大,基本上你能想到的事情都能帮你完成,但同时过于庞大的框架也给人很大的压力。

这么多年使用c#的经验告诉我,能用c#的东西就尽量用,这样既可以提高编程效率,又可以减少程序的错误。

Linq是c#3.5添加进来的新特性,也是c#里面我最喜欢的编程框架之一,我现在基本上很多时候都在用Linq在编程,今天就来谈谈一些本人对于使用Linq进行函数式编程的体会。

Linq是啥东西就不用多介绍了,关于函数式编程,网上也有很多介绍的资料,我感觉函数式编程和c#这类命令式编程最大的不同就是:

函数式编程是对问题本身的表述,而命令式编程则是对问题解决过程的描述

不知道我的感觉大家同不同意,下面就来一段示例说明一下,这是一个同学问我的问题,他说他用c弄了好几个晚上都没弄好(哈哈,我这个同学不是计算机专业的,所以可以理解哈):

问题描述:

八个数 1 4 3 25 26 25 28 29  分成两组,具体算法:
算出平均值=X
标准差=s
ga=X-s
gb=X+s
da[i]=abs(x[i]-ga)
db[i]=abs(x[i]-gb)
比较da[i]和db[i]
若da[i]<db[i] 则x[i]分到a组
大于则分到b组

过程还算是比较复杂吧,如果用传统的方法,就是一堆的for循环什么的,我看了之后觉得用Linq来写会方便很多,于是用10分钟写完了下面的代码:

 1 static void Main(string[] args)
 2         {
 3             var arr = new int[] {1,4 ,3, 25, 26, 25 ,28, 29  };
 4             var x = arr.Average();
 5             var s = Math.Sqrt(arr.Select(a=>a-x).Select(b => b*b).Average());
 6             var ga = x - s;
 7             var gb = x + s;
 8             var da = arr.Select(i => Math.Abs(i - ga));
 9             var db = arr.Select(i => Math.Abs(i - gb));
10             var group = Enumerable.Range(0, arr.Length).GroupBy(i => da.ElementAt(i) < db.ElementAt(i));
11             foreach (var g in group)
12             {
13                 Console.WriteLine("-----------------------------------");
14                 foreach (var e in g)
15                 {
16                     Console.Write(arr[e] + "  ");
17                 }
18                 Console.WriteLine();
19             }
20         }

输出结果

加上初始化和结果输出,只有20行,相当简单哈~~~

从代码来看,基本上就是这个算法过程的表述,过程相当清晰,不存在任何逻辑混乱的地方,这就是函数式编程强大的地方!!!可能有人会说这程序的效率怎样,呵呵,这个问题还挺难回答的,不过我这里只是说明函数式编程的便捷性,并没有太多考虑到运行效率。

于是我接着用Linq实现了一个快速排序算法(其实可以直接使用OrderBy的~~)

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var arr = new byte[200000];
 6             new Random().NextBytes(arr);
 7             foreach (var i in QuickSort(arr))
 8             {
 9                 Console.Write(i + " ");
10             }
11         }
12         static IEnumerable<byte> QuickSort(IEnumerable<byte> arr)
13         {
14             if (arr.Count() <= 1)
15             {
16                 return arr;
17             }
18             else
19             {
20                 var pivot = arr.First();
21                 return arr.GroupBy(i => i.CompareTo(pivot))
22                     .OrderBy(k=>k.Key)
23                     .SelectMany(g => g.Key == 0 ? g : QuickSort(g));
24             }            
25         }
26     }

运行效率还是相当不错的

posted @ 2013-05-18 23:34  ILoveSleep  阅读(659)  评论(0编辑  收藏  举报