package exercise4;
public class E09_Filbonacci {
static long Filbo(int n){
switch(n){
case 1:return 1; //there is no need for break,because "return" is enough
case 2:return 1;
default: return Filbo(n-1)+Filbo(n-2);
}
}
public static void main(String[] args){
for(int i=1;i<=50;i++){
if(i%10==0)
System.out.println(Filbo(i));
else
System.out.print(Filbo(i)+" ");
}
}
}
这个实现了菲波那切数列,但是算到后面运算地非常慢,请问各位有什么好办法麽?
**********************************神奇的分割线******************************************
好开心啊,今早遇到的关于filbonacci数列的问题,刚好在下午上课看数据结构与算法那本书的时候就碰到这个例子:
原来从第四位开始,可以证明到菲波那切数列以1.5为底成指数式的增长,同时程序的运行时间也以指数式增长,所以当到达40以后,运算量显著增长。
本质是因为程序当中存在大量的计算冗余和浪费:
比如F(n)=F(n-1)+F(n-2) 这个表达式;
计算机在运算n-1的时候就隐含了n-2的值了,但是在运算完就把这个值给舍弃了,所以没有在运算F(n-2)的时候又重新算了一遍,造成了时间上的大量浪费。
后来再论坛上也问了下,感谢提供的解决方案:(可以讲每一步的结果缓存起来,避免了递归时的浪费)
public static void fibo(int n){
int[] arr = new int[n];
for(int i=0;i<n&&i<2;i++){
arr[i] = 1;
}
for(int i=2;i<n;i++){
arr[i] = arr[i-1]+arr[i-2];
}
System.out.println(Arrays.toString(arr));
}
或者也可以是这个:
public static void fibo(int n){
int a = 1;
int b = 1;
int c = 0;
for(int i=2;i<n;i++){
c = a + b;
System.out.println(c);
a = b;
b = c;
}
}
感觉第二个更好,因为有点像《计算机网络》中数据传输时的滑动窗口一样,很有意思。
最终我采用了如下的程序:
public class Fibo {
public static long fil(int n){
long a=1;
long b=1;
long c=0;
if(n==1) return 1;
else if(n==2) return 1;
else if(n>2){
for (int i=3;i<=n;i++){
c=a+b;
a=b;
b=c;
}
return c;
}
else{
System.out.println("the number cannot be lower than zero");
return 0;
}
}
public static void main(String[] args){
for(int i=1;i<=90;i++){
if(i%10==0)
System.out.println(fil(i));
else
System.out.print(fil(i)+" ");
}
}
}