Fibonacci序列(雪球版)
(源代码在Algorithms解决方案中的Fibonacci_Snowball工程里
大家好!又见面了~我比较乐意叫这个版本叫雪球版,因为它的计算过程就好象一个滚雪球的过程——越滚越大。
我就不再解释太多Fibonacci的知识了,递归的那个傻孩子版本里已经介绍够多了,估计它还在辛苦地算着1000阶的结果呢,哎呀,傻是没药治的呀,Oh,my god!
这个版本能在线性时间(也就是n是多少,大概就要花n*k的时间,k是一个常数,和你机器跑得多快有关系)里完成,而傻孩子版的应该是2的n次方吧,这个差距已经不能用大人和小孩来比喻了,我想.....我想该用印尼盾和欧元比吧(写这句话的时候 1 歐洲通貨 等於 12368.218 印尼盾).而其中更用了一个小技巧来节省了一个64位,也就是8字节的内存空间,这是多伟大的发明啊(...可惜不是我发明的)!在内存受限的环境里真是一寸土地一板砖金!至于具体的内容,看源代码罗~没什么好说的了,这么简单的算法,拿来当热身还嫌温度不够咧.不过最好理解我想说明的问题:为什么要用不同的方法来解决同样的问题,答案很明显,就是不想做傻孩子。
程序片段:
// Finbonacci_t 是我定义的一个数据类型,被定义为__int64
Fibonacci_t Fibonacci_Showball::Evaluate()
{
if ( _n <= 1 )
return 1;
// 这里我想耍下酷哦~呵呵,你想到的正常方式是不是,先把 fib_junior + fib_senior 结果保存在临时
// 变量里,然后把fib_senior赋值给fib_junior,再把临时变量的结果赋值给fib_senior呢?呵呵,注意
// 看我耍的魔术哦。
Fibonacci_t fib_junior = 1;
Fibonacci_t fib_senior = 1;
for ( int i = 2; i<=_n; ++i )
{
fib_senior += fib_junior;
fib_junior = fib_senior - fib_junior; // 发现什么了吗?没有第3个临时变量哦!
}
return fib_senior; // 看什么看,当然是返回结果罗,没有再多的内容了
}
测试数据:
F(25)=121393 Time elapsed:0
F(26)=196418 Time elapsed:0
F(27)=317811 Time elapsed:0
F(28)=514229 Time elapsed:0
F(29)=832040 Time elapsed:0
F(30)=1346269 Time elapsed:0
F(31)=2178309 Time elapsed:0
F(32)=3524578 Time elapsed:0
F(33)=5702887 Time elapsed:0
F(34)=9227465 Time elapsed:0
F(35)=14930352 Time elapsed:0
F(36)=24157817 Time elapsed:0
F(37)=39088169 Time elapsed:0
F(38)=63245986 Time elapsed:0
F(39)=102334155 Time elapsed:0
F(40)=165580141 Time elapsed:0
看见威力了吗?傻孩子们,快觉悟吧!