[Java实现]Filbonacci斐波那契数列递归带来的问题和改进

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)+"   ");
		}
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值