原文链接
题目
写一个函数来产生第n个fibonacci数
解答
fibonacci数列的定义如下:
f(1) = f(2) = 1;
f(n) = f(n - 1) + f(n - 2);
根据递推公式,我们很容易写出递归和非递归代码
递归:
/**
* 递归实现fibonacci数列
*/
long long int recursionFib(long long int n)
{
if (n < 1)
return -1;
if (n == 1)
return 1;
if (n == 2)
return 1;
return recursionFib(n - 1) + recursionFib(n - 2);
}
非递归:
/**
* 非递归实现fibonacci数列
*
* T = O(n)
*
*/
long long int nonrecursionFib(int n)
{
if (n < -1)
return -1;
if (n == 1)
return 1;
if (n == 2)
return 1;
long long int i, a, b, c;
for (a = b = 1, i = 3; i <= n; i ++) {
c = a + b;
a = b;
b = c;
}
return c;
}
非递归的时间复杂度已经是O(n),看起来简单快速,可是,我们还有更快的解决方法。根据上面的递推公式,我们可以得到它的矩阵版本:
继续化简得:
从上图可以看出,写成矩阵递推形式,可以让我们一推到底。最后的f(1) = f(2) = 1,因此,这个问题就转换成了,如何求矩阵的幂。要快速,不然就没什么意义了。我们先把问题退化一下,先不考虑矩阵的幂,如何求一个整数的幂。
/**
* 求data的n次幂
*/
void numpow(long long int data, int n)
{
long long int i, rs;
for (i = 1, rs = 1; i <= n; i ++) {
rs *= data;
}
printf("%lld\n", rs);
}
时间复杂度为O(n).现在让我们来考虑一种更快速的方法,假设我们要求m^13,然后我们把13写成二进制形式13 = 1101,一开始结果res = 1,我们要计算的幂可以写成:
m^13 = m^1 * m^4 * m^8
我们可以很直观的得出,如果指数13的二进制形式1101中某一位是1,那么,res就去乘以那一位对应的一个数
/**
* 快速求data的n次幂
*
* T = O(logn)
*
*/
void quickPow(long long int data, int n)
{
long long int res;
res = 1;
while (n) {
if (n & 1) res *= data;
data *= data;
n >>= 1;
}
printf("%lld\n", res);
}
时间复杂度为O(logn),正是我们想要的快速版本。OK,这时候如果让你快速求矩阵的幂,是不是很简单了?只需要将实数乘法改成矩阵乘法即可
long long int s[2][2] = {{1, 0}, {0, 1}};
long long int f[2][2] = {{1, 1}, {1, 0}};
/**
* 矩阵乘法
*/
void multiMatrix(long long int c[2][2], long long int a[2][2], long long int b[2][2])
{
long long int i, j, k, t[2][2];
memset(t, 0, sizeof(t));
for (i = 0; i < 2; i ++) {
for (j = 0; j < 2; j ++) {
t[i][j] = 0;
for (k = 0; k < 2; k ++) {
t[i][j] += a[i][k] * b[k][j];
}
}
}
for (i = 0; i < 2; i ++) {
for (j = 0; j < 2; j ++)
c[i][j] = t[i][j];
}
}
/**
* 快速求fibonacci数列
*
* T = O(logn)
*
*/
long long int quickFib(int n, long long int s[2][2], long long int f[2][2])
{
if (n < 1) return -1;
if (n == 1 || n == 2) return 1;
n = n - 2;
while (n) {
if (n & 1) multiMatrix(s, f, s);
multiMatrix(f, f, f);
n >>= 1;
}
return s[0][0] + s[0][1];
}
分享到:
相关推荐
Fibonacci数列斐波那契数列PPT学习教案.pptx
斐波那契数列: 在数学上它以递归的方式进行定义,指这样的一个数列:0、1、1、2、3、5、8、13、21、34、55、89、144……,即前两个数为分别为0和1,从第3项开始,每项的值都等于其前两项之和。斐波那契数列Fib(n)用...
本代码使用C++语言书写,编译环境VS2013。...斐波那契数列(Fibonacci Sequence)又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、…… 本代码是练习作品,如有错误或修改,请指正,感谢感谢。
使用C++非递归实现fibonacci数列,对正在学习算法的同学应该挺有帮助的
一 生小兔问题引起的二 它们也产生斐波那契数列三 通项的其他表达式四 斐波那契数列是二阶循环数列五 斐波那契数列的数论性质六 斐波那契数列的其他性质七 某些斐波那契数列之和八 斐波那契数列与连分数九 斐波那契...
C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++斐波那契数列C++...
Fibonacci数列,用c++编写的,非递归的函数调用求Fibonacci数列的第n项
【问题描述】编写函数f,功能是用递归的方法求斐波那契数列的第n项,函数原型为 int f(int n),在主函数中输入一个正整数n,调用函数f求出斐波那契数列的第n项,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,...
递归方法 def fibonacci(n): if n <= 1: return n else: return fibonacci(n-1) + fibonacci(n-2) n = int(input("请输入要计算的斐波那契数列的项数:")) print("斐波那契数列的第", n, "项为:", fibonacci(n)) 2...
程序分析:斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、…… 在数学上,费波那契数列是以递归的方法来定义: F0 = 0 (n=0) F1 = 1 (n=1) Fn ...
递归方法实现斐波那契数列
自斐波那契数列创立以来,它在数学理论和应用上不断显露出至关重要的地位。随着时代的进步,数学家们发掘了其中的数学联系。这无疑地激发了人们进一步探索数学的兴趣,也使人们对数学的了解更加的系统化。斐波那契...
里面是【斐波那契数列】的前100项,可以当做学习过程中对照是否正确等使用,加油!
编写一个Java程序,用于输出Fibonacci数列的前20项。
# 题目:斐波那契数列。 # 程序分析:斐波那契数列(Fibonacci sequence),从1,1开始,后面每一项等于前面两项之和。图方便就递归实现,图性能就用循环。
斐波那契数列(肥不拉几数列)斐波那契数列(肥不拉几数列)斐波那契数列(肥不拉几数列)斐波那契数列(肥不拉几数列)斐波那契数列(肥不拉几数列)斐波那契数列(肥不拉几数列)斐波那契数列(肥不拉几数列)...
汇编语言,两种方法计算斐波那契数列的前22项,斐波那契数列,分别用两种方法:递归调用,普通循环加法,使用DOSBox验证
(新课标)2020年高考数学 题型全归纳 斐波那契数列.doc
【C++】斐波那契数列应用的一个实例。这是关于斐波那契数列的一个例子,用C++语言实现
利用数组计算斐波那契数列