A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周刚 中级黑马   /  2012-7-13 23:13  /  4699 人查看  /  24 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 周刚 于 2012-7-13 23:21 编辑

也是很常见的一个递归算法问题,供大家练习
斐波那锲数列:1,1,2,3,5,8,13,21...求出第100项是多少?如果说这一问可以用循环实现。
那么下一问:102334155是数列中的多少项?像这种循环次数未知的,恐怕递归是最好的方法

评分

参与人数 1黑马币 +30 收起 理由
蒋映辉 + 30 赞一个!

查看全部评分

24 个回复

正序浏览

复制代码

无标题.png (291.84 KB, 下载次数: 30)

无标题.png

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
小弟刚学不久,功力不够深厚,但为了能得分也只好献丑了。
一般情况下能用循环解决问题的,都不建议用递归,根据问题要求,我用while循环写了两个函数,并且已经在我机子上运行
class Num
{
        public static long getNum(int n)
        {
                long [] num = new long [n];
                if(n<=2)
                {
                        return 1;
                }
                num[0] = 1;
                num[1] = 1;
                int i = 2;
                while(i<n)
                {
                        num[i] = num[i-1] + num[i-2];
                        i++;
                }
                return num[i-1];
        }
       
        public static int getIndex(long num)
        {
               
                long arr [] = new long[200] ;
                if(num<2)
                {
                        return 1;
                }
                arr[0] = 1;
                arr[1] = 2;
                int n=2;
                do
                {
                        arr[n] = arr[n-1] + arr[n-2];
                        n++;
                }while (arr[n-1]<num);
                if(arr[n -1] == num)
                   return n;
                else
                {
                        System.out.println(num+"不是数列中的元素");
                        return 0;
                }
        }
                public static void main(String args[])
                {
                        long i = getNum(100);
                        int j = getIndex(102334155L);
                        System.out.println("i="+i);
                        System.out.println("j="+j);
                }
       
}
都与LZ提到的第二个问题,也很简单,只要判断每一项的值是否小于给定的数就行了,如果不小于就只有两种情况,要么等于,那么返回下标就行了,如果不等于,那么就说明该数在数列中不存在.
回复 使用道具 举报
  1. class demo {
  2.         public static void main(String[] args) {
  3.                 int n = IndexOf(102334155);
  4.                 System.out.println(n);
  5.                 System.out.println(feibo(n));
  6.         }

  7.         public static int feibo(int num){
  8.                 if(num==1||num==2)
  9.                         return 1;
  10.                
  11.                 return feibo(num-2)+feibo(num-1);
  12.         }

  13.         public static int IndexOf(int num){
  14.                 int sum = 1;
  15.                 int last = 1;
  16.                 int temp;

  17.                 int i = 2;
  18.                 while(true){
  19.                         temp = sum;
  20.                         sum += last;
  21.                         last = temp;
  22.                         i++;
  23.                         if (num <= sum)
  24.                         {
  25.                                 return i;
  26.                         }
  27.                 }
  28.         }
  29. }
复制代码
还是循环省事啊
回复 使用道具 举报
本帖最后由 陈冲 于 2012-7-14 09:43 编辑

昨天晚上睡觉前写的,刚开始学,很多东西都不会,有写的不对的地方,请大家帮忙给指出来
试着运行了一下,递归方法求求斐波那锲数列的时候速度真慢……
  1. /*递归方式求斐波那锲数列*/
  2. class Test
  3. {
  4.     public static void main(String[] args)
  5.     {
  6.         int n=100;
  7.         pringFib(n);
  8.     }

  9.     public static double Fib(int n)
  10.     {
  11.         if(n>2)
  12.         {
  13.             return Fib(n-2)+Fib(n-1);
  14.         }
  15.         else
  16.         {
  17.             return 1;
  18.         }
  19.     }
  20.     public static void pringFib(int n)
  21.     {
  22.         for(int x=1;x<=n;x++)
  23.             if(x!=n)
  24.         {
  25.                 System.out.print(Fib(x)+"    ");
  26.                 if(x%5==0)
  27.                     System.out.println();
  28.         }
  29.             else
  30.                 System.out.print(Fib(x));
  31.         System.out.println();
  32.     }
  33. }
复制代码
  1. /*循环方式求斐波那锲数列*/
  2. class Test
  3. {
  4.     public static void main(String[] args)
  5.     {
  6.         printFib(100);
  7.     }
  8.     public static double[] Fib(double[] arr)
  9.     {
  10.         arr[0]=1;
  11.         arr[1]=1;
  12.         for (int i = 2; i < arr.length; i++) {
  13.             arr[i]=arr[i-2]+arr[i-1];
  14.         }
  15.         return arr;
  16.         
  17.     }
  18.     public static void printFib(int n)
  19.     {
  20.         double[] arr=new double[n];
  21.         Fib(arr);
  22.         for (int i = 0; i < arr.length; i++) {
  23.             if(i!=arr.length-1)
  24.                 System.out.print(arr[i]+"    ");
  25.             else
  26.                 System.out.println(arr[i]);
  27.             if((i+1)%5==0)
  28.                 System.out.println();
  29.         }        
  30.     }
  31. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
  1. //我的算法就是在第一个地方补上0,可能跟别的有点不一样
  2. class Test  {
  3.   

  4.     public static int no=1;


  5.     void cau(double n,double m){
  6.         no++;//用来表示当前算的是第几个数
  7.         double temp=m;
  8.         m=n+m;
  9.         n=temp;
  10.       
  11.         if(100==no){
  12.             System.out.println(m);
  13.             System.exit(0);
  14.         }
  15.           cau(n,m);
  16.     }
  17.     public static void main(String[] args) {
  18.         new Test().cau(0,1);
  19.     }
  20. }
复制代码
亲自手打  附上测试图

QQ拼音截图未命名.png (52.89 KB, 下载次数: 78)

QQ拼音截图未命名.png

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
achilles 发表于 2012-7-14 03:23
你都肯承认是搜的还厚颜?真正厚颜的是那些直接百度来答案 改改骗分的人 呵呵 ...

嗯  这位哥们儿正解..
回复 使用道具 举报
yufeiant 发表于 2012-7-14 01:23
在网上搜索了一下,发现有一篇类似的帖子,不过求的结果是前100项的和,厚颜学习,改进了一下,哎,结果可 ...

你都肯承认是搜的还厚颜?真正厚颜的是那些直接百度来答案 改改骗分的人 呵呵
回复 使用道具 举报
在网上搜索了一下,发现有一篇类似的帖子,不过求的结果是前100项的和,厚颜学习,改进了一下,哎,结果可以打印出第一百项了
import java.util.ArrayList;
import java.util.List;

public class TestDemo {
        public static void main(String[] args) {
                List<Long> list = new ArrayList<Long>();
               
                for(int i = 1;i <= 100;i++){
                        if(i <= 2){
                                list.add(new Long(1));
                        }else{
                                long value = list.get(i-2) + list.get(i - 3);
                                list.add(new Long(value));
                        }
                       
                }
                        System.out.print(list.get(list.size()-1).longValue() + "  ");
        }
}
第一百项是
3736710778780434371  
回复 使用道具 举报
发现第一个弄了好久第一百项却没有弄出来,所以就先把第二个发上来了
import java.util.LinkedList;
class Demo {
        public static void main(String[] args) {
                //思路:可以用循环来实现,用数组来存储,发现不行,可不可以转成字符串来进行呢
                long [] arr = new long[100];
                arr[0]=arr[1] = 1;
               
                for (int x=2;x<=100 ;x++ )
                {
                        arr[x] = arr[x-1]+arr[x-2];
                        if(arr[x]==102334155)
                                {
                                        System.out.println(x);
                                        break;
                                }
                }
               
        }
}
打印的结果是第39项,

点评

还是你真个清晰,代码清晰,思路清晰,我喜欢!  发表于 2012-7-14 01:38

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
周刚 发表于 2012-7-14 00:00
哦,sorry我随便写的,100项可能太大了,可能Long都不能表示,那用BigDecimal不知道可否? ...

....................
回复 使用道具 举报
黑马振鹏 发表于 2012-7-13 23:58
算法没问题 关键是第100项到底是什么数字呢,应该用什么类型来存储?

哦,sorry我随便写的,100项可能太大了,可能Long都不能表示,那用BigDecimal不知道可否?
回复 使用道具 举报
温少邦 发表于 2012-7-13 23:48
求项数也能不用递归吧,从头求各项,然后判断就可以了


嗯,兄弟很有才!思路很活跃,建议加分!
回复 使用道具 举报
算法没问题 关键是第100项到底是什么数字呢,应该用什么类型来存储?

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
求项数也能不用递归吧,从头求各项,然后判断就可以了

  1. public class Fibonacci{
  2.         private static int[] add=new int[100];
  3.         private static int pos=0;
  4.         public static int getPos(int i){
  5.                 if(i<2)
  6.                         return -1;
  7.                 add[0]=1;
  8.                 add[1]=1;
  9.                 pos=1;
  10.                 while(i-add[pos]>0){
  11.                         pos++;
  12.                         add[pos]=add[pos-1]+add[pos-2];
  13.                 }
  14.                 if(i-add[pos]==0)
  15.                         return pos;
  16.                 else
  17.                         return -1;
  18.         }
  19.         public static void main(String[] args){
  20.                 System.out.println(getPos(102334155));
  21.         }
  22. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1 赞一个!

查看全部评分

回复 使用道具 举报
丁二跃 发表于 2012-7-13 23:39
64 ………… 一直在跑着

呵呵,这是个问题,我设成20,共移动了1048575次。
回复 使用道具 举报
韦念欣 黑马帝 2012-7-13 23:45:58
9#
使用动态规划,这样快一些,时间复杂度也比较小。
回复 使用道具 举报
周刚 发表于 2012-7-13 23:27
不会吧,这么夸张?!两个多小时,哥们真可以。你把层数设成了多少?

64 ………… 一直在跑着:(
回复 使用道具 举报
许瑞航 发表于 2012-7-13 23:29
public class Test
{
    public int compute(int a)

果然是这么回事、我还是回去老实的看视频吧、
回复 使用道具 举报
public class Test
{
    public int compute(int a)
    {
        if(a == 1 || a ==2)
        {
            return 1;
        }
        else
        {
            return compute(a - 1) + compute(a - 2);
        }
    }
   
    public static void main(String[] args)
    {
        Test test = new Test();
        System.out.println(test.compute(8));
    }
}


用递归很简单吧 斐波那锲

点评

你试试用循环和数组做呢 更简单.....  发表于 2012-7-13 23:31

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马