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);//返回当前项,核心递归
    			}
    		}
    	}
    

      

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

  • 相关阅读:
    MySQL 子查询
    mysql3
    mysql2
    mysql
    C语言理论知识
    冒泡排序
    猜数字游戏
    WPF清爽酷炫的界面Mahapps.metro
    如何在.net4.0中使用.net4.5的async/await
    在C#中使用官方驱动操作MongoDB
  • 原文地址:https://www.cnblogs.com/zpoor/p/7554934.html
Copyright © 2011-2022 走看看