惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
Help Net Security
Help Net Security
P
Proofpoint News Feed
J
Java Code Geeks
爱范儿
爱范儿
Last Week in AI
Last Week in AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
Google DeepMind News
Google DeepMind News
H
Help Net Security
G
Google Developers Blog
Jina AI
Jina AI
Vercel News
Vercel News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
Lohrmann on Cybersecurity
S
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
Security Archives - TechRepublic
Security Archives - TechRepublic
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic
GbyAI
GbyAI
B
Blog
O
OpenAI News
博客园_首页
Cisco Talos Blog
Cisco Talos Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News: Ask HN
Hacker News: Ask HN
TaoSecurity Blog
TaoSecurity Blog
腾讯CDC
MongoDB | Blog
MongoDB | Blog
M
MIT News - Artificial intelligence
C
Cybersecurity and Infrastructure Security Agency CISA
Cyberwarzone
Cyberwarzone
Webroot Blog
Webroot Blog
Simon Willison's Weblog
Simon Willison's Weblog
Y
Y Combinator Blog
C
Cisco Blogs
A
Arctic Wolf
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
AI
AI
W
WeLiveSecurity
aimingoo的专栏
aimingoo的专栏
The Register - Security
The Register - Security
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
Blog — PlanetScale
Blog — PlanetScale

博客园 - greater

Matlab 7.0不断重启问题解决方法 安装Matlab过程中遇到拒绝访问怎么办? NUnit图解(一) [翻译]Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition 第二十四章 LINQ API编程(三) [翻译]Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition 第二十四章 LINQ API编程(二) [翻译]Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition 第二十四章 LINQ API编程(一) 迷人舞步 难译的英文单词 Linq 之Expression Tree再思考 VS2008代码段快捷方式小记 Linq To SQL分页失败后引发的思考 Linq之查询非泛型集合 函数式编程的浅议 Linq操作符之筛选特定位置的元素 Linq的那些事——从Linq扩展方法回顾C#语言基础 Linq To Object实例之过滤字符集 Linq之C#3.0语言扩展 Linq to DataSet 之Access查询 从101 LINQ Samples开始
Linq与斐波那契数列共舞
greater · 2008-06-11 · via 博客园 - greater

从学习算法开始就免不了递归实现一个有趣的题目——斐波那契数列。生于公元1170年的意大利数学家列昂纳多·斐波那契通过兔子的繁殖来引入这样一个数列:1,1,2,3,5,8,13,21……这个数列从第三项开始,每一项都等于前两项之和。它的通向公式:(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}。如果用C语言等通过递归方式实现它非常的简单如下面所示:

1long fibonacci(long n)
2{
3    if(n == 0 || n == 1)
4        return n;
5    else
6        return fibonacci(n-1+ fibonacci(n-2);
7}

然而如果我们结合Linq的Lambda语句实现它又如何呢?这里必须澄清的是Lambda语句与Lambda表达式类似,只是语句在大括号中:

(parameters)=>{statement;}

和匿名方法一样,Lambda语句无法创建表达式目录树。由此引发了我们通过委托来帮助Lambda语句实现该数列的假想。先回顾一下之前委托调用的方法:

第一:通过明确定义匹配的函数原型
这也是最早的委托,先定义一个函数实体,然后相应的定义委托类型,最后通过声明一个变量来调用它,如下所示:

static double Square(double source)
{
   
return Math.Pow(source, 2);
}


delegate double CallMethod(double input);

CallMethod callMethod1 
= Square;
Console.WriteLine(callMethod1(
3));

第二:实例化泛型委托Func<T,TResult>(这种类型的委托还有好几个)
同样的要定义具体的函数,不同的是不需要定义具体的委托类型,而是通过实例化Func泛型委托来实现,如:

Func<doubledouble> callMethod2 = Square;
Console.WriteLine(callMethod2(
3));

第三:通过Func<T,TResult>与匿名方法一起使用
通过这种方式减轻了复杂度,并且提高了代码的可读性。如下:

Func<doubledouble> callMethod3 = delegate(double input) return Math.Pow(input, 2); };

第四:通过Lambda表达式或Lambda语句
这也是相对来说比较简单的方式,它通过泛型委托定义函数和Lambda表达式实现功能的方式来实现。

Func<doubledouble> callMethod4 = d => Math.Pow(d, 2);
Console.WriteLine(callMethod4(
3));

由此可知,泛型委托在Lambda实现上有着链接和协调的作用。因此在这个意义上讲我们通过两种泛型委托的实现第一种是Action<T1,T2,T3>,该委托用于封装一个方法,该方法采用三个参数并且没有返回值。第二种是Func<T1,TResult>,该委托封装一个具有一个参数并且返回TResult参数指定类型值的方法。必须应用System.Core.dll命名空间System;

根据命题,我们设定实现两种目标的函数,分别命名为Fibonacci_A和Fibonacci_B,前者实现给出前两个数打印出在n之前的斐波那契数,后者则实现打印出前n个斐波那契数。对于递归的方法两个函数的具体实现会有所不同。

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

               
if (secondNum > boundNum)
               
{
                   
return;
               }

               
else
           
{
                   Console.WriteLine(exchangeNum );
                   MethodBase.GetCurrentMethod().Invoke(
nullnew 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(nullnew object[] { n - 2 })) 
                       
+Convert.ToInt32(MethodBase.GetCurrentMethod().Invoke(nullnew object[] { n - 1 })));
               }
;

           
for (int i = 0; i < 10; i++)
           
{
               Console.WriteLine(Fibonacci_B(i));
           }

为了实现委托自身的递归调用两个函数都通过反射来实现。

通过这两个简单的递归函数,让我们更加了解了Lambda语句的高级功能。以上的函数不一定是最简练的,希望有更好的方法的朋友把它贴出来,以之共勉。