为了融入黑马浓郁的学习氛围,昨天参加了斑竹们举行答题的活动,本来一个简单的猴子吃桃问题,我却做了很久,深深的打击了我的信心,这种题按道理在我4、5年前就能轻轻松松解决。现在做了这么多年的程序,居然思维禁锢到这个地步了。看到题我最开始的想法是,这个一看就是算法方面的题,主要考察的是算法,找一下里面数据之间的关系,建立数学模型应该能解决,但是既然用 java 解决,那么就需要用面向对象思维来考虑啦。我把整个问题看做一个系统,猴子、桃子组成的系统。这个系统发生的事情就是每天猴子吃桃这样一个用例。具体怎么吃我先不管,这样做是依据面向对象思维方式:先整体,后局部,先抽象,后具体。我认为只要描述出来这个系统,自然可以得到系统的每个细节。于是我写下了如下代码:- class MonkeyAndPeachMain
- {
- public static void main(String[] args)
- {
- LinkedList<Peach> peachStorage = new LinkedList<Peach>();
- Monkey monkey = new Monkey();
- monkey.pickPeach(peachStorage);
- monkey.eatPeach(peachStorage);
- }
- }
复制代码 这里面主要有两个类,一个集合类。Monkey 和 Peach 类用来描述猴子和桃子,LinkedList<Peach> 用来描述很多桃子的集合。下面是完整实现代码:- class MonkeyAndPeachMain
- {
- public static void main(String[] args)
- {
- LinkedList<Peach> peachStorage = new LinkedList<Peach>();
- Monkey monkey = new Monkey();
- monkey.pickPeach(peachStorage);
- monkey.eatPeach(peachStorage);
- }
- }
- class Monkey
- {
- /**
- * @param peachStorage 桃子仓库
- */
- public void pickPeach(LinkedList<Peach> peachStorage, int peachAcount)
- {
- peachStorage.clear();
- int count = 0;
- while(count < peachAcount)
- {
- peachStorage.add(new Peach());
- count++;
- }
- }
- /**
- * @param peachStorage 桃子仓库
- */
- public int eatPeach(LinkedList<Peach> peachStorage)
- {
- int peachStorageSize = peachStorage.size();
- if(peachStorageSize%2 != 0)
- {
- // 如果桃子数不能被平均分为一般就说明桃子数
- // 量有问题,这个地方也可以用异常来描述
- return -2;
- }
- int count = 0;
- while(count < (peachStorageSize/2+1))
- {
- if(peachStorage.poll() == null)
- {
- return -1; // 如果仓库桃子吃完了,也说明桃子数量有问题
- }
- count++;
- }
- return 1;
- }
- }
- class Peach
- {
- }
复制代码 但是我郁闷了,因为猴子 pickPeach 函数摘的桃子的总数是未知的,而 Java 不是 Matlab 可以解方程,pickPeach 函数中始终有个变量没有初始化,不能执行。这个时候我脑袋里面始终都有着以前思维的干扰,就是列个方程,找一下规律,或许可以得到桃子的总数,但是那种思维方式明显不是我现在想要的解决问题的思路,这两种思路就一种冲突着。还有就是开始我以为限时半个小时,一看时间,半个小时都过了,我那个灰心,想想两种思路一个都没有做出来。水平真的倒退了啊。学习方法真的有问题啊。后面我妥协了,我去找了一下规律,发现前一天和后一天的桃子的个数始终是一个固定的关系,而最后一天的桃子的个数是知道的,那么倒着算总可以得出桃子的总数了吧。于是写了如下可以运行的代码:- /**
- 需求:猴子吃桃的问题:猴子第一天摘下来N个桃子,当天就吃了一半,但是还不过瘾,又多吃了一个,第二天早上
- 又将剩下的桃子吃了一半,又多吃了一个,以后每天早上都吃了前一天剩下的一半零一个,到第十天早上的时候
- 就发现剩下一个桃子了.求第一天一共摘下了多少桃子呢?
- 思路:
- 从这个文字的描述看,这个系统中包含的对象可以有猴子、桃子、桃子集合,整个系统发生的事情就是猴子
- 摘桃子、吃桃子,最后需要知道猴子第一天摘了多少桃子。如果把这个系统用计算机描述出来,并模拟系统
- 的运行,是可以知道猴子第一条摘多少桃子的。因为开始不知道猴子摘了多少桃子,所以只能逆着模拟系统
- 的正常情况来模拟运行。
- 步骤:
- 1.系统要运行需要桃子仓库,用来保存桃子,桃子仓库用可以动态增删元素的集合来表示
- 2.还需要猴子,猴子要有吃桃子的行为,由于是逆着模拟系统,所以根据当天剩余的桃子数量可以计算出当
- 天猴子吃掉的桃子,然后把猴子吃掉的保存进桃子仓库,这样就得到了上一天的仓库的桃子剩余数量,一直
- 递归调用猴子吃桃,直到 10 天前
- 3.把猴子吃掉10天后桃子仓库的数量打印出来就是猴子摘的桃子的总量
- */
- import java.util.*;
- class MonkeyAndPeachMain
- {
- public static void main(String[] args)
- {
- LinkedList<Peach> peachStorage = new LinkedList<Peach>();
- Monkey monkey = new Monkey();
- peachStorage.add(new Peach()); // 因为最后一天还剩一个桃,所以先把仓库里面放一个桃子
- monkey.eatPeach(peachStorage, 1);
- System.out.println("猴子总共摘了 " + peachStorage.size() + " 个桃子");
- }
- }
- class Monkey
- {
- /**
- * @param peachStorage 桃子仓库
- * @param day 猴子吃桃的天数
- */
- public void eatPeach(LinkedList<Peach> peachStorage, int day)
- {
- if(day >= 10)
- {
- return;
- }
- else
- {
- int currentPeachAcount = 0;
- int peachStorageSize = peachStorage.size();
- while(currentPeachAcount < (2*(peachStorageSize+1)-peachStorageSize))
- {
- peachStorage.add(new Peach());
- currentPeachAcount++;
- }
- eatPeach(peachStorage, day+1);
- }
- }
- }
- class Peach
- {
- }
复制代码 最后我也只是提交了这个代码。整个过程花了1个多小时。完全打击了自信心啊,这也说明我应该修改一下学习方法,以前我一直仗着自己基础好,很少练习,基本上是看看视频,总结总结。现在发现这个学习方法肯定有问题啊,独学而无友,孤陋而寡闻啊,我一直只追求思考方式,需要写代码的时候我连数组的定义格式都忘了。后来我就在论坛上搜索了一下java学习方法的帖子,有一个很不错哦, 他还把方法写到了博客里面,http://blog.163.com/ichuanbo@126/blog/static/1667061462013488332953/,所以朋友们啊我们一定要经常上论坛交流啊。最后我想到其实前面的那个正向思维的方式未必不能用代码实现,不是缺一个桃子的总数么,其实可以一个一个数测试,哪个数让程序运行没有问题就算是正确结果嘛。测试的时候可以只测试偶数。实现结果如下:- import java.util.*;
- class MonkeyAndPeachMain2
- {
- public static void main(String[] args)
- {
- LinkedList<Peach> peachStorage = new LinkedList<Peach>();
- Monkey monkey = new Monkey();
- System.out.println("猴子总共摘了 " + MonkeyEatPeach(peachStorage, monkey) + " 个桃子");
- }
- public static int MonkeyEatPeach(LinkedList<Peach> peachStorage, Monkey monkey)
- {
- peachAcountLoop:
- for(int peachAcount = 1;;peachAcount++)
- {
- monkey.pickPeach(peachStorage, 2*peachAcount);
- for(int day = 0; day < 10; day++)
- {
- switch (monkey.eatPeach(peachStorage))
- {
- case -1:
- continue peachAcountLoop;
- case -2:
- if(day == 9)
- {
- return 2*peachAcount;
- }
- continue peachAcountLoop;
- }
-
- }
- return 2*peachAcount;
- }
- }
- }
- class Monkey
- {
- /**
- * @param peachStorage 桃子仓库
- */
- public void pickPeach(LinkedList<Peach> peachStorage, int peachAcount)
- {
- peachStorage.clear();
- int count = 0;
- while(count < peachAcount)
- {
- peachStorage.add(new Peach());
- count++;
- }
- }
- /**
- * @param peachStorage 桃子仓库
- */
- public int eatPeach(LinkedList<Peach> peachStorage)
- {
- int peachStorageSize = peachStorage.size();
- if(peachStorageSize%2 != 0)
- {
- // 如果桃子数不能被平均分为一般就说明桃子数
- // 量有问题,这个地方也可以用异常来描述
- return -2;
- }
- int count = 0;
- while(count < (peachStorageSize/2+1))
- {
- if(peachStorage.poll() == null)
- {
- return -1; // 如果仓库桃子吃完了,也说明桃子数量有问题
- }
- count++;
- }
- return 1;
- }
- }
- class Peach
- {
- }
复制代码 |