黑马程序员技术交流社区

标题: Java自学感言 [打印本页]

作者: toShareBeauty    时间: 2013-6-16 13:03
标题: Java自学感言
为了融入黑马浓郁的学习氛围,昨天参加了斑竹们举行答题的活动,本来一个简单的猴子吃桃问题,我却做了很久,深深的打击了我的信心,这种题按道理在我4、5年前就能轻轻松松解决。现在做了这么多年的程序,居然思维禁锢到这个地步了。看到题我最开始的想法是,这个一看就是算法方面的题,主要考察的是算法,找一下里面数据之间的关系,建立数学模型应该能解决,但是既然用 java 解决,那么就需要用面向对象思维来考虑啦。我把整个问题看做一个系统,猴子、桃子组成的系统。这个系统发生的事情就是每天猴子吃桃这样一个用例。具体怎么吃我先不管,这样做是依据面向对象思维方式:先整体,后局部,先抽象,后具体。我认为只要描述出来这个系统,自然可以得到系统的每个细节。于是我写下了如下代码:
  1. class MonkeyAndPeachMain
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 LinkedList<Peach> peachStorage = new LinkedList<Peach>();
  6.                 Monkey monkey = new Monkey();

  7.                 monkey.pickPeach(peachStorage);
  8.                 monkey.eatPeach(peachStorage);
  9.         }
  10. }
复制代码
这里面主要有两个类,一个集合类。Monkey 和 Peach 类用来描述猴子和桃子,LinkedList<Peach> 用来描述很多桃子的集合。下面是完整实现代码:
  1. class MonkeyAndPeachMain
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 LinkedList<Peach> peachStorage = new LinkedList<Peach>();
  6.                 Monkey monkey = new Monkey();

  7.                 monkey.pickPeach(peachStorage);
  8.                 monkey.eatPeach(peachStorage);
  9.         }
  10. }

  11. class Monkey
  12. {
  13.         /**
  14.          * @param peachStorage        桃子仓库
  15.          */
  16.         public void pickPeach(LinkedList<Peach> peachStorage, int peachAcount)
  17.         {
  18.                 peachStorage.clear();
  19.                 int count = 0;
  20.                 while(count < peachAcount)
  21.                 {
  22.                         peachStorage.add(new Peach());
  23.                         count++;
  24.                 }
  25.         }

  26.         /**
  27.          * @param peachStorage        桃子仓库
  28.          */
  29.         public int eatPeach(LinkedList<Peach> peachStorage)
  30.         {
  31.                 int peachStorageSize = peachStorage.size();
  32.                 if(peachStorageSize%2 != 0)
  33.                 {
  34.                         // 如果桃子数不能被平均分为一般就说明桃子数
  35.                         // 量有问题,这个地方也可以用异常来描述
  36.                         return -2;
  37.                 }

  38.                 int count = 0;
  39.                 while(count < (peachStorageSize/2+1))
  40.                 {
  41.                         if(peachStorage.poll() == null)
  42.                         {
  43.                                 return -1; // 如果仓库桃子吃完了,也说明桃子数量有问题
  44.                         }
  45.                         count++;
  46.                 }
  47.                 return 1;
  48.         }
  49. }

  50. class Peach
  51. {
  52. }
复制代码
但是我郁闷了,因为猴子 pickPeach 函数摘的桃子的总数是未知的,而 Java 不是 Matlab 可以解方程,pickPeach 函数中始终有个变量没有初始化,不能执行。这个时候我脑袋里面始终都有着以前思维的干扰,就是列个方程,找一下规律,或许可以得到桃子的总数,但是那种思维方式明显不是我现在想要的解决问题的思路,这两种思路就一种冲突着。还有就是开始我以为限时半个小时,一看时间,半个小时都过了,我那个灰心,想想两种思路一个都没有做出来。水平真的倒退了啊。学习方法真的有问题啊。后面我妥协了,我去找了一下规律,发现前一天和后一天的桃子的个数始终是一个固定的关系,而最后一天的桃子的个数是知道的,那么倒着算总可以得出桃子的总数了吧。于是写了如下可以运行的代码:
  1. /**
  2. 需求:猴子吃桃的问题:猴子第一天摘下来N个桃子,当天就吃了一半,但是还不过瘾,又多吃了一个,第二天早上
  3. 又将剩下的桃子吃了一半,又多吃了一个,以后每天早上都吃了前一天剩下的一半零一个,到第十天早上的时候
  4. 就发现剩下一个桃子了.求第一天一共摘下了多少桃子呢?

  5. 思路:
  6. 从这个文字的描述看,这个系统中包含的对象可以有猴子、桃子、桃子集合,整个系统发生的事情就是猴子
  7. 摘桃子、吃桃子,最后需要知道猴子第一天摘了多少桃子。如果把这个系统用计算机描述出来,并模拟系统
  8. 的运行,是可以知道猴子第一条摘多少桃子的。因为开始不知道猴子摘了多少桃子,所以只能逆着模拟系统
  9. 的正常情况来模拟运行。


  10. 步骤:
  11. 1.系统要运行需要桃子仓库,用来保存桃子,桃子仓库用可以动态增删元素的集合来表示
  12. 2.还需要猴子,猴子要有吃桃子的行为,由于是逆着模拟系统,所以根据当天剩余的桃子数量可以计算出当
  13. 天猴子吃掉的桃子,然后把猴子吃掉的保存进桃子仓库,这样就得到了上一天的仓库的桃子剩余数量,一直
  14. 递归调用猴子吃桃,直到 10 天前
  15. 3.把猴子吃掉10天后桃子仓库的数量打印出来就是猴子摘的桃子的总量
  16. */
  17. import java.util.*;

  18. class MonkeyAndPeachMain
  19. {
  20.         public static void main(String[] args)
  21.         {
  22.                 LinkedList<Peach> peachStorage = new LinkedList<Peach>();
  23.                 Monkey monkey = new Monkey();

  24.                 peachStorage.add(new Peach());        // 因为最后一天还剩一个桃,所以先把仓库里面放一个桃子
  25.                 monkey.eatPeach(peachStorage, 1);

  26.                 System.out.println("猴子总共摘了 " + peachStorage.size() + " 个桃子");
  27.         }
  28. }

  29. class Monkey
  30. {
  31.         /**
  32.          * @param peachStorage        桃子仓库
  33.          * @param day                        猴子吃桃的天数
  34.          */
  35.         public void eatPeach(LinkedList<Peach> peachStorage, int day)
  36.         {
  37.                 if(day >= 10)
  38.                 {
  39.                         return;
  40.                 }
  41.                 else
  42.                 {
  43.                         int currentPeachAcount = 0;
  44.                         int peachStorageSize = peachStorage.size();
  45.                         while(currentPeachAcount < (2*(peachStorageSize+1)-peachStorageSize))
  46.                         {
  47.                                 peachStorage.add(new Peach());
  48.                                 currentPeachAcount++;
  49.                         }
  50.                         eatPeach(peachStorage, day+1);
  51.                 }
  52.         }
  53. }

  54. class Peach
  55. {
  56. }
复制代码
最后我也只是提交了这个代码。整个过程花了1个多小时。完全打击了自信心啊,这也说明我应该修改一下学习方法,以前我一直仗着自己基础好,很少练习,基本上是看看视频,总结总结。现在发现这个学习方法肯定有问题啊,独学而无友,孤陋而寡闻啊,我一直只追求思考方式,需要写代码的时候我连数组的定义格式都忘了。后来我就在论坛上搜索了一下java学习方法的帖子,有一个很不错哦, 他还把方法写到了博客里面,http://blog.163.com/ichuanbo@126/blog/static/1667061462013488332953/,所以朋友们啊我们一定要经常上论坛交流啊。最后我想到其实前面的那个正向思维的方式未必不能用代码实现,不是缺一个桃子的总数么,其实可以一个一个数测试,哪个数让程序运行没有问题就算是正确结果嘛。测试的时候可以只测试偶数。实现结果如下:
  1. import java.util.*;

  2. class MonkeyAndPeachMain2
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 LinkedList<Peach> peachStorage = new LinkedList<Peach>();
  7.                 Monkey monkey = new Monkey();

  8.                 System.out.println("猴子总共摘了 " + MonkeyEatPeach(peachStorage, monkey) + " 个桃子");
  9.         }

  10.         public static int MonkeyEatPeach(LinkedList<Peach> peachStorage, Monkey monkey)
  11.         {
  12.         peachAcountLoop:
  13.                 for(int peachAcount = 1;;peachAcount++)
  14.                 {
  15.                         monkey.pickPeach(peachStorage, 2*peachAcount);
  16.                         for(int day = 0; day < 10; day++)
  17.                         {
  18.                                 switch (monkey.eatPeach(peachStorage))
  19.                                 {
  20.                                 case -1:
  21.                                         continue peachAcountLoop;
  22.                                 case -2:
  23.                                         if(day == 9)
  24.                                         {
  25.                                                 return 2*peachAcount;
  26.                                         }
  27.                                         continue peachAcountLoop;
  28.                                 }
  29.                                        
  30.                         }
  31.                         return 2*peachAcount;
  32.                 }
  33.         }
  34. }

  35. class Monkey
  36. {
  37.         /**
  38.          * @param peachStorage        桃子仓库
  39.          */
  40.         public void pickPeach(LinkedList<Peach> peachStorage, int peachAcount)
  41.         {
  42.                 peachStorage.clear();
  43.                 int count = 0;
  44.                 while(count < peachAcount)
  45.                 {
  46.                         peachStorage.add(new Peach());
  47.                         count++;
  48.                 }
  49.         }

  50.         /**
  51.          * @param peachStorage        桃子仓库
  52.          */
  53.         public int eatPeach(LinkedList<Peach> peachStorage)
  54.         {
  55.                 int peachStorageSize = peachStorage.size();
  56.                 if(peachStorageSize%2 != 0)
  57.                 {
  58.                         // 如果桃子数不能被平均分为一般就说明桃子数
  59.                         // 量有问题,这个地方也可以用异常来描述
  60.                         return -2;
  61.                 }

  62.                 int count = 0;
  63.                 while(count < (peachStorageSize/2+1))
  64.                 {
  65.                         if(peachStorage.poll() == null)
  66.                         {
  67.                                 return -1; // 如果仓库桃子吃完了,也说明桃子数量有问题
  68.                         }
  69.                         count++;
  70.                 }
  71.                 return 1;
  72.         }
  73. }

  74. class Peach
  75. {
  76. }
复制代码

作者: 黄炳期    时间: 2013-6-16 13:29
楼主好认真!继续努力!





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