zoukankan      html  css  js  c++  java
  • 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+"秒");
            
            //此处下面可以直接通过给相关类传递参数,实现相应功能,上面的中代码仅仅提供示例
        }
    
    }
    
    
  • 相关阅读:
    HDU_1846 Brave Game(sg函数简化版)
    POJ 3225 Help with Intervals(线段树)
    ZOJ_3501 Roman Order
    HDU_1527 取石子游戏(威佐夫博弈)
    HDU_2112 HDU Today(DIjkstra + map映射)
    HDU_3339 In Action(Dijkstra + DP)
    单链表的实现(课本上的算法)
    haproxy 基于 uri 实现调度
    haproxy 基于 cookie 实现 session 绑定
    [转]ASP.NET 虚拟主机安全漏洞解决方案
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12948227.html
Copyright © 2011-2022 走看看