菲波那契数列(Fibonacci sequence)指的是这样一个数列:
1,1,2,3,5,8,13,21,34,55,……
这个数列从第三项开始,每一项都等于前两项之和。可将其递归定义为:
F(1) = 1
F(2) = 1
F(n) = F(n - 1) + F(n - 2) n > 2
因此,可用递归的办法编写程序计算该数列第 N 项的值:
// header inherited from ISO C
#include <cassert> // for assert
// boost header
#include <boost/bigint.hpp> // for bigint
boost::bigint fibonacci(const boost::bigint &n)
{
assert(n != 0);
if ( n == 1 || n == 2 ) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
不过,递归效率实在是太差了,不信你可以试试计算第 50 项的值,看看需要多久。使用迭代可以大大提高运行效率:
boost::bigint fibonacci(const boost::bigint &n)
{
assert(n != 0);
if ( n == 1 || n == 2 ) return 1;
boost::bigint tmp, f1 = 1, f2 = 1;
for ( boost::bigint i = 2; i != n; ++i )
{
tmp = f1 + f2;
f1.swap(f2);
f2.swap(tmp);
}
return f2;
}
这回计算第 50 项的值一下子就出来了。
此外,也可以使用公式来计算第 N 项的值:
Boost 库目前似乎还没有针对 bigint 进行开方及求 N 次方的函数(若有请告知),故此,鄙人也就暂不将该公式代码化啦。
下面这个函数的功能是构建一个 n 项的菲波那契数列
// ISO C++ header
#include <vector>
// header inherited from ISO C
#include <cassert> // for assert
// boost header
#include <boost/bigint.hpp> // for bigint
void form_fib_seq(std::vector<boost::bigint>::size_type n, // 菲波那契数列的项数
std::vector<boost::bigint> &vFibSeq) // 用于保存菲波那契数列
{
assert(n != 0); // 项数不能为 0
if ( n > 2 ) // 如果需要构建的数列的项数大于 2
{
// 先将第一、二项的值保存到容器里
vFibSeq.push_back(1);
vFibSeq.push_back(1);
for ( std::vector<boost::bigint>::size_type i = 2;
i != n; ++i )
{
// 从第三项开始,每一项都等于前两项之和
vFibSeq.push_back(vFibSeq[i - 1] + vFibSeq[i - 2]);
}
}
else // 如果需要构建的数列的项数小于/等于 2
{
while ( n-- != 0 )
{
vFibSeq.push_back(1);
}
}
}
斐波那契序列有着广泛的应用。
1)例如有一种两个游戏,名叫“尼姆”。游戏方法是由两个人轮流取一堆粒数不限的砂子。先取的一方可以取任意粒,但不能把这堆砂子全部取走。后取的一方,取数也多少不拘,但最多不能超过对方所取砂子数的一倍。然后又轮到先取的一方来取,但也不能超过对方最后一次所取砂子的一倍。这样交替地进行下去,直到全部砂子被取光为止,谁能拿到最后一粒砂子,谁就算胜利者。
在这个游戏中,若所有砂子的粒数是个斐波那契数的话,那么后取的一方稳操胜券,而所有的砂子不是一个斐波那契数的话,那么先取的一方稳胜。
2) 一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。
3 ) 兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔都不死,那么一年以后可以繁殖多少对兔子?
斐波那契数列的整除性与素数生成性
每3个数有且只有一个被2整除, 每4个数有且只有一个被3整除, 每5个数有且只有一个被5整除, 每6个数有且只有一个被8整除, 每7个数有且只有一个被13整除, 每8个数有且只有一个被21整除, 每9个数有且只有一个被34整除, .......
斐波那契数与植物花瓣
3………………………百合和蝴蝶花 5………………………蓝花耧斗菜、金凤花、飞燕草、毛茛花 8………………………翠雀花 13………………………金盏 和玫瑰 21………………………紫宛 34、55、89……………雏菊