Java实现斐波那契数列的多种方法

小编综合了很多算法相关的书籍以及其他,总结了几种求斐波那契数列的方法

PS:其中的第83行的递归法是求斐波那契数列的经典方法


public class 斐波那契数列 {
	
	  //迭代法
    public static int iteration(int n){   /*此处(包含下面所有方法)声明为静态方法,原因是在本类main()方法中调用
        类中方法,对于一般的非static成员变量或方法,需要有一个对象的实例才能调用,所以要先生成对象的实例,他们才会实际的分配内存空间。
        而对于static的对象或方法,在程序载入时便已经分配了内存空间,他只和特定的类想关联,无需实例化  */
        int result = 1;  //最后一个斐波那契数
        int a[] = new int[n+1];    //存放斐波那契数,初始值为空,默认全为0
        a[0] = 0;
        a[1] = 1;
        //System.out.println("迭代法计算斐波那契数结果:");
        //System.out.print(a[0]+"  "+a[1]+"  ");
        for(int i = 2;i < n+1;i++){
            a[i] = a[i-1] + a[i-2];
            //result = a[i];
            //System.out.print(result+"  ");        //打印斐波那契数
        }
        //System.out.println();
        result=a[n];
        return result;    //返回最后一个斐波那契数
    }
    
    //用迭代法寻找编程环境支持的最大整数(int型)的斐波那契数是第几个斐波那契数
    public static int max_int_iteration(){
        int a = 1,b = 1,c = 2;
        int count = 3;
        for( ;b < c; ){   //一旦c达到编程环境最大斐波那契数,便会产生内存溢出,从而变成一个负数,到此循环结束
            a = b;
            b = c;
            c = a + b;
            count++;
        }
        return count;
    }
    
    
    //用迭代法寻找编程环境支持的最大整数(long型)的斐波那契数是第几个斐波那契数
    public static long max_long_iteration(){
        long a = 1,b = 1,c = 2;
        long count = 3;
        for( ;b<c; ){    //一旦c达到编程环境最大斐波那契数,便会产生内存溢出,从而变成一个负数,到此循环结束
            a = b;
            b = c;
            c = a + b;
            count++;
        }
        return count;
    }
    
    //在1,5,10,50秒内使用迭代法算出的最大斐波那契数是第几个
        public static void time_iteration(){
            int a = 1,b = 1,c = 2;
            long count = 3;
            long a1 = 0,a2 = 0,a3 = 0,a4 = 0;
            long t1 = System.currentTimeMillis(); 
            long t2 = System.currentTimeMillis();
            for( ;t2-t1 < 60000; ){   
                a = b;
                b = c;
                c = a + b;
                count++;
                t2 = System.currentTimeMillis(); 
                if(t2-t1 == 1000)
                    a1 = count;
                    //System.out.println("1秒内最大斐波那契数是第:"+count+"个 ");
                if(t2-t1 == 5000)
                    a2 = count;
                    //System.out.println("5秒内最大斐波那契数是第:"+count+"个 ");
                if(t2-t1 == 10000)
                    a3 = count;
                    //System.out.println("10秒内最大斐波那契数是第:"+count+"个 ");
                if(t2-t1 == 50000)
                    a4 = count;
                    //System.out.println("50秒内最大斐波那契数是第:"+count+"个 ");
            }
            System.out.println("迭代法1秒内最大斐波那契数是第:"+a1+"个 ");
            System.out.println("迭代法5秒内最大斐波那契数是第:"+a2+"个 ");
            System.out.println("迭代法10秒内最大斐波那契数是第:"+a3+"个 ");
            System.out.println("迭代法50秒内最大斐波那契数是第:"+a4+"个 ");
        }
    
    //递归法
    public static long recursion(long n){
        long result = 0;   //最后一个斐波那契数及存储中间斐波那契数的变量
        if(n <= 0)
            result = 0;
        if(n == 1 || n == 2)
            result = 1;
        if(n > 2)
        {
            result = recursion(n-1) + recursion(n-2);
            //System.out.print(result+"  ");
        }
        return result;
    }
    
    //规定时间内,递归法计算出的最大斐波那契数是第几个
    public static int recursion_time(long time){
        long starttime_dg=System.currentTimeMillis();
        int i=3;
        long endtime_dg=0;
        while(endtime_dg<starttime_dg+time*1000){
        endtime_dg=System.currentTimeMillis();
        i++;
        recursion(i);
        }
        return i;
        }
    
    //递归法在1,5,10,50秒内算出的最大斐波那契数是第几个
    public static void fbnq_recursion_time(){
        
              System.out.println("1秒内最大斐波那契数是第:"+recursion_time(1)+"个 ");
          
              System.out.println("5秒内最大斐波那契数是第:"+recursion_time(5)+"个 ");
          
              System.out.println("10秒内最大斐波那契数是第:"+recursion_time(10)+"个 ");
          
              System.out.println("50秒内最大斐波那契数是第:"+recursion_time(50)+"个 ");
        
        
        }
    
    //测试递归法在1,5,10,50秒内使用迭代法算出的最大斐波那契数是第几个
    public static void time_recursion_test(){
        long t1 = System.currentTimeMillis(); 
        long t2 = 0;
        int i = 3;        
        for(;t2-t1 > 60000;){
            recursion(i);
            i++;
            t2 = System.currentTimeMillis();
            if(t2-t1 == 1000)
                System.out.println("1秒内最大斐波那契数是第:"+i+"个 ");
            if(t2-t1 == 5000)
                System.out.println("5秒内最大斐波那契数是第:"+i+"个 ");
            if(t2-t1 == 10000)
                System.out.println("10秒内最大斐波那契数是第:"+i+"个 ");
              if(t2-t1 == 50000)
                System.out.println("50秒内最大斐波那契数是第:"+i+"个 ");
            
        }
    }
    
    //直接求值法(利用公式F(n) = [@n/sqrt(5)]快速计算第n个斐波那契数)
    public static double formula(int n){
        double result = 0;
        double temp = Math.sqrt(5.0);
        result =  (1/temp)*(Math.pow((1+temp)/2,n)-Math.pow((1-temp)/2, n));
        return result;
    }
    
    
    //利用直接求值法,出现误差时最小的n值
    public static int min_formula(){
        double result_fn=1;
        int i=1;
        while(result_fn-(double)iteration(i)<1){
        result_fn=formula(i);
        i++;
        }
        return i;
    }
    
    //新算法法
    public static int new_way(int n){
        //int a = 1,b = 1,c = 2,d = 3;
        int result = 0;   //定义最后一个斐波那契数
        //根据输入n,求出最后一个斐波那契数
        if(n == 0)
            result = 0;
        else if(n == 1 || n == 2)
            result =  1;
        else if(n == 3)
            result =  2;
        else if(n >= 4){    //若n大于4返回resul
            int a1 = n/4;
            int b1 = n%4;
            int a = new_way(a1);
            int b = new_way((a1+1));
            int c = new_way((a1-1));
            int d = new_way((a1+2));
            if(b1 == 0)
                result = (int) ((Math.pow(b,2) - Math.pow(c,2))*(Math.pow(c, 2) + 2*Math.pow(a, 2) + Math.pow(b,2)));
            if(b1 == 1)
                result = (int) (Math.pow((Math.pow(b,2) - Math.pow(c,2)),2) + Math.pow((Math.pow(a, 2) + Math.pow(b,2)),2));
            if(b1 == 2)
                result = (int) ((Math.pow(a, 2) + Math.pow(b,2))*(3*Math.pow(b,2)+Math.pow(a, 2)-2*Math.pow(c,2)));
            if(b1 == 3)
                result = (int) (Math.pow((Math.pow(a, 2) + Math.pow(b,2)),2) + Math.pow((Math.pow(d,2)-Math.pow(a,2)),2));
        
        }
            return result;
    }
    
    
    // 关联矩阵  
    private static final int[][] UNIT = { { 1, 1 }, { 1, 0 } };  
    // 全0矩阵  
    private static final int[][] ZERO = { { 0, 0 }, { 0, 0 } };  
    /** 
     * 求斐波那契数列 
     *  
     * @param n 
     * @return 
     */  
    public static int[][] fb(int n) {  
        if (n == 0) {  
            return ZERO;  
        }  
        if (n == 1) {  
            return UNIT;  
        }  
        // n是奇数  
        if ((n & 1) == 0) {  
            int[][] matrix = fb(n >> 1);  
            return matrixMultiply(matrix, matrix);  
        }  
        // n是偶数  
        int[][] matrix = fb((n - 1) >> 1);  
        return matrixMultiply(matrixMultiply(matrix, matrix), UNIT);  
    }  
      
    /** 
     * 矩阵相乘 
     *  
     * @param m 
     *            r1*c1 
     * @param n 
     *            c1*c2 
     * @return 新矩阵,r1*c2 
     */  
    public static int[][] matrixMultiply(int[][] m, int[][] n) {  
        int rows = m.length;  
        int cols = n[0].length;  
        int[][] r = new int[rows][cols];  
        for (int i = 0; i < rows; i++) {  
            for (int j = 0; j < cols; j++) {  
                r[i][j] = 0;  
                for (int k = 0; k < m[i].length; k++) {  
                    r[i][j] += m[i][k] * n[k][j];  
                }  
            }  
        }  
        return r;  
    }  
    
    //具体实现矩阵相乘算法
    public static int matrix(int n){
        int[][] m = fb(n); 
        return m[0][1];
    }
    
    public static void main(String[] args){
        System.out.print(max_int_iteration());
        System.out.println();
        System.out.print(max_long_iteration());
        System.out.println();
        System.out.println();
        long t1 = System.currentTimeMillis();  
        long a = recursion(47);
        long t2 = System.currentTimeMillis();
        System.out.println("递归法求斐波那契数:");
        System.out.println(a);
        System.out.println("递归算法Time is: " + (t2 - t1)/1000.0+"秒");
        
        //此处下面可以直接通过给相关类传递参数,实现相应功能,上面的中代码仅仅提供示例
    }

}

posted @ 2019-07-12 21:27  南墙1  阅读(95)  评论(0编辑  收藏  举报