fibonacci的几种实现及尾递归

来源:互联网 发布:过五如何清理数据 编辑:程序博客网 时间:2024/06/08 13:09
Java代码  收藏代码
  1. /** 
  2.  * java version "1.6.0_17"<br> 
  3.  * 尾递归与迭代实现具有相当的性能;<br> 
  4.  * 缓存实现的性能略高于非尾递归实现;<br> 
  5.  * 递归:recursive  尾递归:tail recursive;<br> 
  6.  * 尾递归时不需保存方法调用栈的参数及返回结果;于是申请的栈帧会被及时回收 
  7.  */  
  8. public class TestFibo {  
  9.   
  10.     public static void main(String[] args) {  
  11.         int N=50;  
  12.         long begin=System.currentTimeMillis();        
  13.         System.out.println(fibo1(N)); //fibo1  
  14.         System.out.println(System.currentTimeMillis()-begin);  
  15.           
  16.         begin=System.currentTimeMillis();  
  17.         System.out.println(fibo2(N)); //fibo2  
  18.         System.out.println(System.currentTimeMillis()-begin);  
  19.           
  20.         begin=System.currentTimeMillis();  
  21.         System.out.println(fibo3(N)); //fibo3  
  22.         System.out.println(System.currentTimeMillis()-begin);  
  23.           
  24.         begin=System.currentTimeMillis();  
  25.         System.out.println(fibo4(N)); //fibo4  
  26.         System.out.println(System.currentTimeMillis()-begin);  
  27.     }  
  28. //1.1 非尾递归实现(书本上经常出现)    
  29. public static long fibo1(long n){    
  30.     if(n<2return n;    
  31.     return fibo1(n-1)+fibo1(n-2); //小心栈溢出    
  32. }    
  33. //1.2 缓存实现(JS good part里有过介绍)    
  34. public static int LENGTH=30//过大了就会占用过多空间    
  35. public static long[] cache=new long[LENGTH];    
  36. public static long fibo2(int n){    
  37.     if(n<2return n;    
  38.     if(n>=LENGTH){    
  39.         return fibo2(n-1)+fibo2(n-2);    
  40.     }else if(cache[n]==0){    
  41.         cache[n]=fibo2(n-1)+fibo2(n-2); //减少重复计算                
  42.     }    
  43.     return cache[n];    
  44. }    
  45. //1.3 迭代实现    
  46. public static long fibo3(long n){    
  47.     if(n<2return n;    
  48.     long pre=1,prepre=1,ret=0;    
  49.     for(int i=2;i<n;i++){    
  50.         ret=pre+prepre;    
  51.         prepre=pre;    
  52.         pre=ret;    
  53.     }    
  54.     return ret;    
  55. }    
  56. //1.4 尾递归实现    
  57. public static long fibo4(int n){    
  58.     if(n<2return n;    
  59.     return fibo4Helper(n, 113); //保持与非尾递归接口不变,是借助帮助方法实现尾递归的    
  60. }    
  61. private static long fibo4Helper(int n,long prepre,long pre,int begin){    
  62.     if(n==begin) return pre+prepre;    
  63.     return fibo4Helper(n, pre, prepre+pre, ++begin);    //这里相当于迭代实现for-loop的浓缩      
  64. }   
  65.       
  66.     //----------------------尾递归的其他实现-------------------------------------->  
  67.     //2. 求最大公约数  
  68.     public static int gcd(int big,int small){  
  69.         if(big%small==0return small;  
  70.         return gcd(small, big%small);  
  71.     }  
  72.     //3.1 阶乘--非尾递归  
  73.     public static int fn1(int n){  
  74.         if(n<2return 1;  
  75.         return n*fn1(n-1);  
  76.     }  
  77.     //3.2 阶乘--尾递归  
  78.     public static int fn2(int n){  
  79.         if(n<2return 1;  
  80.         return fn2Helper(1, n);  
  81.     }  
  82.     private static int fn2Helper(int ret, int n){  
  83.         if(n<2return ret;  
  84.         return fn2Helper(ret*n,n-1);  
  85.     }  
  86.         //4.1 翻转字符串--非尾递归  
  87.        public static String reverse1(String s, int length){  
  88.             if(length==0return ""//下一行的"+"可借助高版本JDK编译器的优化  
  89.             return s.charAt(length-1)+reverse1(s,length-1);  
  90.         }  
  91.        //4.2 翻转字符串--尾递归  
  92.        public static String reverse2(String s){  
  93.            return reverse2Helper(s, "", s.length());  
  94.        }  
  95.        private static String reverse2Helper(String s,String init,int len){  
  96.            if(len==0return init;  
  97.            return reverse2Helper(s, init+s.charAt(len-1), len-1);  
  98.        }  
  99.     //5. 验证字符串是否是回文 testHuiwen("abcdcba")  
  100.      public static boolean testHuiwen(String s){  
  101.          return testHuiwenHelper(s, 0, s.length());  
  102.      }  
  103.      private static boolean testHuiwenHelper(String s,int begin, int len){  
  104.          if(begin< len>>1 && s.charAt(begin)==s.charAt(len-begin-1))   
  105.              return testHuiwenHelper(s, begin+1, len);  
  106.          else if(begin==len>>1return true;  
  107.          else return false;  
  108.      }  
  109.     //6. 翻转整数 如:1024=>4201  
  110.      public static int reverseInt(int i){  
  111.          return reverseIntHelper(i, 0);  
  112.      }  
  113.      private static int reverseIntHelper(int i, int init){  
  114.          if(i==0return init;  
  115.          return reverseIntHelper(i/10, init*10+i%10);  
  116.      }  
  117. }  

最后show一下强大的scala,用一行代码获取斐波那契数列的前30位: 
Scala代码  收藏代码
  1. >(1 to 28).foldLeft("0,1")((a,b)=>a+","+a.split(",").takeRight(2).map(_.toInt).reduceLeft(_+_))    
  2.   
  3. >0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229    
  4.   
  5. >(1 to 28).foldLeft(List(1,0))((a,b)=>(a.head+a.tail.head)::a).reverse.mkString(",")    
  6.   
  7. >0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229  
  8.   
  9.   
  10. scala> def fibo(n:Int)=(1 to n).foldLeft(List(0,1))((a,b)=>a:+(a.init.last+a.last))  
  11. fibo: (n: Int)List[Int]  
  12.   
  13. scala> fibo(10)  
  14. res4: List[Int] = List(01123581321345589)  
0 0
原创粉丝点击