zoukankan      html  css  js  c++  java
  • 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     }

    运行效率还是相当不错的

  • 相关阅读:
    c++设计模式:工厂模式(Factory Pattern)
    lua和tolua++的安装
    c++设计模式:观察者模式(Observer Pattern)
    c++设计模式:抽象工厂模式(Abstract Factory Pattern)
    linux下搭建eclipsec++开发环境
    c++设计模式:单件模式(Singleton Pattern)
    SQL SERVER查询Job每个步骤执行结果情况
    XMLA清空Cube缓存
    【转载】SSIS 包组件的命名规则
    SQL SERVER 游标删除无数据试图
  • 原文地址:https://www.cnblogs.com/ILoveSleep/p/3086365.html
Copyright © 2011-2022 走看看