黑马程序员技术交流社区
标题:
Java自学感言
[打印本页]
作者:
toShareBeauty
时间:
2013-6-16 13:03
标题:
Java自学感言
为了融入黑马浓郁的学习氛围,昨天参加了斑竹们举行答题的活动,本来一个简单的猴子吃桃问题,我却做了很久,深深的打击了我的信心,这种题按道理在我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
{
}
复制代码
作者:
黄炳期
时间:
2013-6-16 13:29
楼主好认真!继续努力!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2