黑马程序员技术交流社区

标题: 拓展题-生兔子的四种解法,欢迎交流! [打印本页]

作者: jyf823691221    时间: 2015-10-15 16:11
标题: 拓展题-生兔子的四种解法,欢迎交流!
  1. /*
  2. 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,
  3. 假如兔子都不死,问每个月的兔子对数为多少?
  4. 程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21....
  5. */

  6. /*
  7. 下面是我想到的几种解法,其实都是一个原理,只是在代码上的体现不同
  8. 如果大家有更加好的解法欢迎讨论~
  9. */

  10. //第一种(递归):
  11. class Rabbits1 {
  12.         public static void main(String[] args) {
  13.                 int month = 10;
  14.                 System.out.println("第" + month + "个月的兔子数是: " + getNumOfRabbits(month));
  15.         }
  16.         //根据月份计算兔子数量
  17.         public static int getNumOfRabbits(int month) {
  18.                 if (month == 1 || month == 2) { //如果是前两个月份的话兔子数是固定的,无需进行计算,返回1即可
  19.                         return 1;
  20.                 }

  21.                 //如果月份超过2的话兔子数就需要知道前两个月份才能算出来
  22.                 //因此函数返回的值总是前两个月兔子数的和
  23.                 return getNumOfRabbits(month - 2) + getNumOfRabbits(month - 1);
  24.         }
  25. }

  26. /*
  27. 上面一种递归的方法可能不太好理解,并且目前基础java班并没有将递归
  28. 下面采用数组的办法做
  29. */

  30. //第二种(使用数组):
  31. class Rabbits2 {
  32.         public static void main(String[] args) {
  33.                 int month = 10;
  34.                 System.out.println("第" + month + "个月的兔子数是: " + getNumOfRabbits(month));
  35.         }
  36.         public static int getNumOfRabbits(int month) {
  37.                 //要计算第n个月的兔子数,就需要一个长度为n的数组
  38.                 int[] numOfRabbits = new int[month];

  39.                 //第一个月和第二个月的兔子数是固定的
  40.                 numOfRabbits[0] = 1;
  41.                 numOfRabbits[1] = 1;

  42.                 //高能开始
  43.                 //现在开始计算第 三个月 到第 month 个月的兔子数
  44.                 //因为数组索引是从0开始的,所以m的初始值是 3 - 1
  45.                 for (int m = 2; m < month; ++m) {
  46.                         //第m个月的兔子数等于 m-1 个月加上 m-2 个月的兔子数
  47.                         numOfRabbits[m] = numOfRabbits[m - 2] + numOfRabbits[m - 1];
  48.                 }

  49.                 //打印第 1 个月到第 month 个月的兔子数
  50.                 System.out.println("每个月的兔子数:");
  51.                 for (int i = 0; i < numOfRabbits.length; ++i) {
  52.                         System.out.print(numOfRabbits[i] + "\t");
  53.                 }

  54.                 //数组的最后一项就是第month个月的兔子数
  55.                 return numOfRabbits[numOfRabbits.length - 1];
  56.         }
  57. }

  58. //既然能用数组,并且计算的数据需要的变量来回都是那三个,是不是可以只用三个变量进行计算呢?
  59. //第三种(小内存版):

  60. class Rabbits3 {
  61.         public static void main(String[] args) {
  62.                 int month = 10;
  63.                 System.out.println("第" + month + "个月的兔子数是: " + getNumOfRabbits(month));
  64.         }
  65.         public static int getNumOfRabbits(int month) {
  66.                 if (month == 1 || month == 2) { //前两个月不用算,直接返回 1 好了
  67.                         return 1;
  68.                 }

  69.                 //高能开始
  70.                 //定义三个变量,分别用于存储进行计算的三个月份的兔子数
  71.                 int aaa = 1; //上上个月兔子的数量
  72.                 int aa = 1;  //上个月兔子的数量
  73.                 int a = 0;   //当前月兔子的数量

  74.                 //由于前两个月兔子数量是不用计算的,因此要计算第 month 个月兔子数只需要计算 month - 2 次即可
  75.                 //这就是说

  76.                 month -= 2;
  77.                 while (month > 0) {
  78.                         a = aaa + aa; //当前月兔子数 = 上个月兔子数 + 上上个月兔子数
  79.                         aaa = aa;     //将上个月兔子数交由上上个月那个变量,因为下次计算的时候已经不再需要那个值
  80.                         aa = a;       //将本月兔子数交由上个月变量保存
  81.                         //这样 经过一轮计算,我们得到了本月兔子数并且还有上个月的兔子数

  82.                         month--;
  83.                 }

  84.                 return a; //返回当月兔子数
  85.         }
  86. }

  87. /*
  88. 似乎每次在循环中运算之后我们只需要保存当月的和上个月的兔子数就
  89. 能够在下次循环中计算出下个月的兔子数,因此这个版本仅仅只是减少
  90. 了一个变量,但在内存使用上并不占优势
  91. */

  92. //第四种(最少变量):

  93. class Rabbits4 {
  94.         public static void main(String[] args) {
  95.                 int month = 10;
  96.                 System.out.println("第" + month + "个月的兔子数是: " + getNumOfRabbits(month));
  97.         }
  98.         public static int getNumOfRabbits(int month) {
  99.                 if (month == 1 || month == 2) { //前两个月不用算,直接返回 1 好了
  100.                         return 1;
  101.                 }

  102.                 int aaa = 1; //上上个月兔子的数量
  103.                 int aa = 1;  //上个月兔子的数量

  104.                 month -= 2;
  105.                 while (month > 0) {
  106.                        
  107.                         //参考一条语句交换两个变量的值的那种写法,就不解释了
  108.                         aa = aaa + aa * 2 - (aaa = aa);

  109.                         month--;
  110.                 }

  111.                 return aa; //返回兔子数
  112.         }
  113. }
复制代码

作者: 请叫我齐岛主    时间: 2015-10-15 18:06
6666666666666666
作者: 某某徐    时间: 2015-10-15 18:12
已经看过了了了了了
作者: 某某徐    时间: 2015-10-15 18:15
原来是要10个字以上的。
作者: shiawase    时间: 2015-10-15 18:21
加油!!!!!!!!!!!!!!!!!!!!!!!!!!
作者: shiawase    时间: 2015-10-15 18:23
这种帖子不加分吗?给我们这样的菜鸟很大的帮助啊
作者: shiawase    时间: 2015-10-16 21:24
楼主加油把另外49道题做出来,我看好你!
作者: shiawase    时间: 2015-10-16 21:44
楼主加油把另外49道题做出来,我看好你!
作者: Sniper-L    时间: 2015-10-16 22:05
过来看看!不错啊
作者: shiawase    时间: 2015-10-16 23:38
加油!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
作者: shiawase    时间: 2015-10-17 00:04
加油!加油!加油!加油!加油!加油!加油!加油!加油!
作者: 无言唯笑    时间: 2015-10-17 00:32
分析的很详细啊!
作者: shiawase    时间: 2015-10-17 08:23
楼主加油把另外49道题做出来,我看好你!
作者: shiawase    时间: 2015-10-17 08:24
楼主加油把另外49道题做出来,我看好你!
作者: shiawase    时间: 2015-10-17 08:27
楼主加油把另外49道题做出来,我看好你!
作者: shiawase    时间: 2015-10-17 09:16
楼主加油把另外49道题做出来,我看好你!
作者: 水小新    时间: 2015-10-21 21:29
大神    来膜拜了{:2_30:}
作者: 水小新    时间: 2015-10-30 21:51
    很好很强大!!长知识了
作者: 水小新    时间: 2015-10-31 21:43
          这个题方法确实挺好的    帮住我解决了好多问题




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2