zoukankan      html  css  js  c++  java
  • Java-斐波拉契数列的三种实现方法

    先看下百度百科对斐波拉契数列的定义:

              斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 反正就是一句话:斐波拉契牛逼。

    第一种数组实现方法:基于数组实现

    /**
     * @author 薛定谔的猫
     * 斐波拉契数列数组实现
     * 求前二十项*/
    public class Main {
    	public static void main(String[] args) {
    		getFib(20);
    	}
    	
    	public static int getFib(int n){//核心函数
    		if (n<0) {
    			return -1;//小于0是没有意义的
    		}else if (n == 0) {
    			return 0;//等于0其实也没什么意义
    		}else if (n == 1||n == 2) {
    			return 1;//第一项和第二项都是1
    		}else {
    			int[] fibAry = new int[n + 1];
    			fibAry[0] = 0;
    			fibAry[1] = fibAry[2] = 1;
    			
    			for(int i = 3;i<=n;i++) {
    				fibAry[i] = fibAry[i-1] + fibAry[i-2];//当前项等于后一项加上后两项
    				System.out.println("第" + i + "项"+fibAry[i]);//输出当前项
    			}
    			return fibAry[n];//返回当前项
    		}
    	}
    }
    

      

    第二种实现方法:基于变量实现

    /**
     * @author 薛定谔的猫
     * 斐波拉契数列变量实现
     * 求前二十项*/
    public class Main {
    	public static void main(String[] args) {
    		getFib(20);
    	}
    	
    	public static int getFib(int n){//核心函数
    		if (n<0) {
    			return -1;//小于0是没有意义的
    		}else if (n == 0) {
    			return 0;//等于0其实也没什么意义
    		}else if (n == 1||n == 2) {
    			return 1;//第一项和第二项都是1
    		}else {
    			int temp = 0;//当前项变量
    			int a = 1;//第一项
    			int b = 1;//第二项
    			
    			for(int i = 3;i<=n;i++) {
    				//变量互换值
    				temp = a+b;//当前项等于前两项相加
    				a = b;//前两项互换值
    				b = temp;//当前项赋值给前一项
    				System.out.println("第" + i + "项"+temp);//输出当前项
    			}
    			return temp;//返回当前项
    		}
    	}
    }
    

      

    第三种实现方法:递归实现(用递归的都是神)

            递归定义:简单的说就是自己调用自己。

    /**
     * @author 薛定谔的猫
     * 斐波拉契数列变量实现
     * 求前二十项
     * 这种方法最简单,但是最占用内存,特别是当n很大的时候
     * 
     * 
     * 为什么递归得效率低?
     * 递归效率低是函数调用的开销导致的。在一个函数调用之前需要做许多工作,
     * 比如准备函数内局部变量使用的空间、搞定函数的参数等等,这些事情每次调用函数都需要做
     * ,因此会产生额外开销导致递归效率偏低,所以逻辑上开销一致时递归的额外开销会多一些当然了,
     * 通过有意识的组织代码的写法可以把某些递归写成尾递归,尾递归可以进行特殊的优化所以效率
     * 会比普通的递归高一些,也不会因为递归太多导致栈溢出遍历树还不用递归的话,那么人肉写一个栈
     * +深度优先遍历或者人肉队列+广度优先遍历,再辅以黑魔法给栈或者队列提速,应该会比递归快一些,
     * 加速幅度和语言和写法相关,但在大多数情况下我觉得是得不偿失的,花了很大精力很可能效率提升不
     * 明显
     * 
     * 此回答转自知乎
    
     * */
    public class Main {
    	public static void main(String[] args) {
    		for(int i = 1;i<=20;i++) {
    		System.out.println("第" +i + "项" + getFib(i));
    		}
    	}
    	
    	public static int getFib(int n){//核心函数
    		if (n<0) {
    			return -1;//小于0是没有意义的
    		}else if (n == 0) {
    			return 0;//等于0其实也没什么意义
    		}else if (n == 1||n == 2) {
    			return 1;//第一项和第二项都是1
    		}else {
    				return getFib(n-1) + getFib(n-2);//返回当前项,核心递归
    			}
    		}
    	}
    

      

    最后说一句,斐波拉契牛逼。

  • 相关阅读:
    I.MX6 Surfaceflinger 机制
    理解 Android Fragment
    RPi 2B DDNS 动态域名
    RPi 2B IPC webcam server
    理解 Android MVP 开发模式
    I.MX6 system.img unpack repack
    can't set android permissions
    VMware Ubuntu 共享文件夹
    解决oracle数据库连接不上的问题
    perfect-scrollbar示例
  • 原文地址:https://www.cnblogs.com/zpoor/p/7554934.html
Copyright © 2011-2022 走看看