计算fibonacci数列通常有两种方法,非常符合fibonacci数列公式表达的方法就是使用递归,当x = 1或x = 2时,fab(x) = 1; x > 2时,fac(x) = fac(x - 1) + fac(x - 2);
int fibonacci(int n)
{
if (n <= 2)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
这样可以很方便的使用递归实现算法,但是使用递归计算的话效率非常的低下,因为在后续的计算中执行了大量的重复计算,比如计算fib(4) = fib(3) + fib(2),然后fib(3)递归计算fib(2), fib(1);fib(2)要计算fib(1),从而fib(2)和fib(1)被重复计算了,所以带来了没必要的计算。为了避免这种额外的计算开销,所以有了的循环计算数列的方法。
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int a1 = 1, a2 = 1, n;
cin >> n;
for (int i = 3; i <= n; i++)
{
int t = a1 + a2;
a1 = a2;
a2 = t;
}
cout << a2 << endl;
return 0;
}
因为fibonacci数列的都一项都只与前两项相关,并且起始的两项数据是已知的,所以我们保留两个变量,保存每次计算的前两个数,每次循环中不断求出新的数列项,然后更新这两个变量的值,以便下次循环使用,同样也能实现fibonacci数列常数时间的计算。
还有一个fibonacci数列的通项公式是通项公式是:
a(n)=(√5/5)*{[(1+√5)/2]^n - [(1-√5)/2]^n},但我没用过。
本文的重点是下面这种计算fibonacci数列的方法,其时间复杂度O(log(n));我们用矩阵去实现这个算法,预备知识,矩阵乘法:http://zh.wikipedia.org/wiki/%E7%9F%A9%E9%99%A3%E4%B9%98%E6%B3%95,我们设定基础矩阵为,然后不断用它乘以自己依次得到