今天看到群友发的一个问题:写一个小程序打印第n个斐波那契数。
自己试了下,搞了好久。。。基础要加强了。
进入正题,什么是斐波那契数列就不说了,拿到这个题目,直接写出如下代码:
public static long findFibonacci(int n){
if(n <= 2){
return 1;
}else{
return findFibonacci(n - 1) + findFibonacci(n - 2);
}
}
运行一下,输入n分别为:1,2,3,4,5 输出分别为1,1,2,3,5。貌似是正确的,看看有什么问题,如果我们输入n为45。
public static void main(String[] args) {
long s = System.currentTimeMillis();
System.out.println(findFibonacci(45));
long e = System.currentTimeMillis();
System.out.println("程序运行耗时["+(e-s)+"]毫秒!");
}
输出如下:
1134903170
程序运行耗时[4875]毫秒!
如果输入100的话,就一直在运行。。。。。
上面程序的问题在于,计算第n个f数时需要计算第n-1和第n-2个f数,但是计算第n+1个f数的时候又要重新计算第n个f数,如此反复,要处理的子问题的数量爆炸式增长。我们加点输出看看。
public static long findFibonacci(int n){
if(n <= 2){
System.out.println("计算第["+n+"]个斐波那契数[1]");
return 1;
}else{
long fb = findFibonacci(n - 1) + findFibonacci(n - 2);
System.out.println("计算第["+n+"]个斐波那契数["+fb+"]");
return fb;
}
}
n输入为5,输出如下:
计算第[2]个斐波那契数[1]
计算第[1]个斐波那契数[1]
计算第[3]个斐波那契数[2]
计算第[2]个斐波那契数[1]
计算第[4]个斐波那契数[3]
计算第[2]个斐波那契数[1]
计算第[1]个斐波那契数[1]
计算第[3]个斐波那契数[2]
计算第[5]个斐波那契数[5]
5
程序运行耗时[0]毫秒!
如何解决这个问题呢,如果我们能重复利用子问题的结果,而不是每次去重新求解子问题,这样程序就会快很多,这种处理问题的方式也叫做动态规划。
针对这个问题,假设我们要求第n个斐波那契数,我们可以建立一个长度为n(为n-1就可以,但为了编码方便)的数组用来保存子问题结果,代码如下:
private static long findFibonacci1(int n, long[] c){
int index = n - 1;
if(c[index] != 0){
return c[index];
}
if(n <= 2){
c[index] = 1;
}else{
c[index] = findFibonacci1(n - 1,c) + findFibonacci1(n - 2,c);
}
return c[index];
}
public static long findFibonacci1(int n){
long c[] = new long[n];
return findFibonacci1(n,c);
}
这次输入45,看看结果:
1134903170
程序运行耗时[0]毫秒!
这次没问题了。再想想,其实每次求第n个f数只需要重用第n-1和第n-2个f数就可以了,而且依据代码,问题的解决是自底向上的,所以每次保存2个就够了,我们先搞点日志看看。
private static long findFibonacci1(int n, long[] c){
int index = n - 1;
if(c[index] != 0){
System.out.println("从数组下标["+index+"]中获取数据["+c[index]+"]");
return c[index];
}
if(n <= 2){
c[index] = 1;
}else{
c[index] = findFibonacci1(n - 1,c) + findFibonacci1(n - 2,c);
}
return c[index];
}
输入7,看输出:
从数组下标[1]中获取数据[1]
从数组下标[2]中获取数据[2]
从数组下标[3]中获取数据[3]
从数组下标[4]中获取数据[5]
13
程序运行耗时[0]毫秒!
可以看到,会从小到大从数组中取数据。继续看看能不能每次只保存2个子问题结果。看代码:
private static long findFibonacci2(int n, long[] c){
int index = n % 2;
if(c[index] != 0){
System.out.println("从数组下标["+index+"]中获取数据["+c[index]+"]");
return c[index];
}
if(n <= 2){
c[index] = 1;
}else{
c[index] = findFibonacci2(n - 1,c) + findFibonacci2(n - 2,c);
}
return c[index];
}
public static long findFibonacci2(int n){
long c[] = new long[2];
return findFibonacci2(n,c);
}
输出8,看看输出:
从数组下标[0]中获取数据[1]
从数组下标[1]中获取数据[2]
从数组下标[0]中获取数据[3]
从数组下标[1]中获取数据[5]
从数组下标[0]中获取数据[8]
21
程序运行耗时[0]毫秒!
嗯,果然可以。去掉打印语句,输出1000,看看输出:
817770325994397771
程序运行耗时[0]毫秒!
ok,嘎嘎。不过这道题直接用循环貌似更简单。。。。
再来个更短的(无聊)
private static long f(int n, long[] a){
return a[n & 1] == 0 ? (n <= 2 ? (a[n & 1] = 1)
:(a[n & 1] = f(n - 1, a) + f(n - 2, a))) : a[n & 1];
}
public static long findNthFibonacci(int n){
return f(n, new long[2]);
}
分享到:
相关推荐
这个代码是用来求第N个斐波那契数,仅供交流,不喜勿喷!
【汇编实验——求第N个Fibonacci数】 在计算机科学中,Fibonacci数列是一个非常基础且重要的概念,它在算法设计、数学分析以及各种编程实践中有广泛的应用。Fibonacci数列通常定义为:F(0) = 0, F(1) = 1, 且对于 n...
double Fibonacci(int n) { double f1=0,f2=1,f; int i; for(i=2; i<=n; i++) { f=f1+f2; f1=f2; f2=f; } return f; } int main(void) { int n; double f; printf("请输入n="); scanf("%d",&n); f=Fibonacci(n); ...
函数 求第n个斐波那契数
这是一种效率较高的方法,通过两个变量分别保存前两个斐波那契数,不断更新这两个变量,直到计算出第n个斐波那契数。时间复杂度是O(n)。 6. **闭式公式**: 斐波那契数列有一个公式Fn = (1/sqrt(5)) * [((1+sqrt...
如果你想要在控制台打印斐波那契数列的特定项,可以调用这个函数并传入所需的索引,例如`print(fibonacci(10))`会打印出第10项斐波那契数,即55。 在实际编程中,除了这种方法,还可以使用递归、动态规划或矩阵乘法...
【问题描述】编写函数f,功能是用递归的方法求斐波那契数列的第n项,函数原型为 int f(int n),在主函数中输入一个正整数n,调用函数f求出斐波那契数列的第n项,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,...
输出前n个斐波那契数 c++
对于n大于1的情况,我们使用两个变量`fib`和`prevFib`分别存储当前斐波那契数和前一个斐波那契数,通过循环计算出第n个数。 在Java开发工程师的笔试中,斐波那契数列是一个常见的题目,因为它可以考察候选人的逻辑...
Fibonacci数列是由两个前一个数相加得到的数列,通常以0和1开始:0, 1, 1, 2, 3, 5, 8, 13, 21, ...。递归定义是F(n) = F(n-1) + F(n-2),其中F(0) = 0,F(1) = 1。 在汇编语言中实现Fibonacci数列,我们需要了解...
C语言程序设计-用函数求fibonacci数列前n项的和;说明:fibonacci数列为数列的第一项值为1,第二项值也为1,从第三项开始,每一项均为其前面相邻两项的和;例如:当n=28时,运行结果:832039.c
在Python中,我们可以采用两种主要方法来计算斐波那契数列的第n项: 1. **递归方法**: 这种方法基于斐波那契数列的定义,通过递归调用自身来计算每一项。代码如下: ```python def fibonacci(n): if n ...
在不同的编程语言中查找第 N 个斐波那契数 关于 斐波那契数列是由简单的线性递推关系定义的整数序列。 该序列出现在数学和其他科学的许多环境中。 特别是,许多天然存在的生物体的形状受斐波那契数列及其近亲黄金...
3. 结果:dp[n]就是所求的第n个斐波那契数。 C语言实现斐波那契数列的动态规划代码可能如下: ```c #include int fibonacci(int n) { if (n ) return 0; if (n == 1) return 1; int dp[n+1]; dp[0] = 0; ...
设计内容是编写一个程序,接受用户输入的控制值n,然后计算并显示第n个Fibonacci数。设计时间通常为一周。 在设计过程中,主要使用DOS操作系统,配合文本编辑器(如EDIT)、汇编器(MASM.EXE)、链接器(LINK.EXE)...
在给定的例子中,我们初始化变量`n_1`和`n_2`为斐波那契数列的前两个数,然后在循环中更新它们的值,直到计算出第n个数。这种方法简单易懂,但当n值较大时,效率较低,因为存在大量的重复计算。 ```python n = int...
Fibonacci斐波那契数列,很简单,就是一...要求很简单,输入n,输出第n个Fibonacci数,n为正整数 下面是这九种不同的风格: 1)第一次写程序的Python程序员: def fib(n): return nth fibonacci number 说明: 第
在数学上,第n个斐波那契数有一个公式。 我已经看到该实现称为O(1)。 但是,这依赖于浮点数并执行诸如浮点取幂之类的操作,因此我不确定它的速度或精度或O(1)是多少。 如果没有溢出,此程序将给出确切的答案-...
//第一个数 int n2 = 1;//第二个数 int sum = 0;//和 if(n){ System.out.println("参数错误!"); return; } if(n){ sum = 1; }else{ for(int i=3;i<=n;i++){ sum = n1+n2; n1 = n2; n2 = sum; } } System.out....