裴波那契数列

今天看到一个有趣的数列

1,1,2,3,5,8,13,21....

看这组竖列的特征,我们可以看出从第三个开始,第n个的值登月第n-1个加上第n-2个的值。

其实这就是世界上著名的裴波那契数列

好了,现在我们知道了竖列的规律。假如我想知道第40个的值是多少,小伙伴们有什么解决方案了。

最简单的方式:一个个加上去,呵呵40个很快就出来了

但是,作为程序员哥哥,是不会用这么愚蠢的方式的

转入正题,程序员哥哥要开始工作了。

这不是很简单吗,一个递归算法就搞定了

1 public long Calc(long n){
2 if (n < 1) { throw new IndexOutOfRangeException("n为正整数"); }
if(n==1||n==2){return 1;}
3 return Calc(n-1)+Calc(n-2); 4 }

调用Calc(40);OK,得到值102334155。程序员哥哥很开心的迅速算出了答案。

接下来,有个同学反映说,我想知道更多一点,第100个吧!

程序员哥哥Calc(100);然后就呵呵了,结果是System.StackOverflowException;瞬间在风中凌乱了.....

从结果我们可以很明显看出,这个是栈溢出异常导致的。那么为什么为出现这种情况呢?

我们来看下Calc方法,当n很大的时候,Calc中会嵌套很多的Calc的递推函数,所以就呵呵了.....

既然我们发现了问题的所在,那么就要找到一个解决方案

 1  public class FeiBoNaQiShuLie
 2     {
 3         public IDictionary<long, long> dicShuLie { get; set; }
 4         long max = 0;
 5         public FeiBoNaQiShuLie(long n)
 6         {
 7             if (n < 1) { throw new IndexOutOfRangeException("n为正整数"); }
 8             dicShuLie = new Dictionary<long, long>();
 9             max = n;
10             for (long i = 1; i <= n; i++)
11             {
12                 Calc(i);
13             }
14         }
15         private long Calc(long n)
16         {
17             if (n > 2)
18             {
19                 return CacheCalcValue(n - 1) + CacheCalcValue(n - 2);
20             }
21             return 1;
22         }
23         private long CacheCalcValue(long n)
24         {
25             long last;
26             if (dicShuLie.ContainsKey(n))
27             {
28                 last = dicShuLie[n];
29             }
30             else
31             {
32                 last = Calc(n);
33                 dicShuLie[n] = last;
34             }
35             return last;
36         }
37         public long Value(long n)
38         {
39             if (n > max) { throw new IndexOutOfRangeException("n 不能超过" + max); }
40             return dicShuLie[n];
41         }
42     }

 

看代码可以看出,在FeiBoNaQiShuLie类中,增加了一个字典用于保存Calc计算处理啊的值。

在某种程度上解决了刚才的问题。

但这里又有其他的瓶颈,包括字典的存储容量。如果n过大,初始化工作要好久,这里面有性能的问题,还可以继续优化

具体的,就先写到这里了...优化的工作,后面有空再补充。

我贴出这个代码,不过是为了提供一个解决问题的思路而已。

posted @ 2015-12-08 17:42  AntColony  阅读(522)  评论(0)    收藏  举报