黑马程序员技术交流社区
标题:
迟来的基础测试,好在赶上了末班车。
[打印本页]
作者:
noiary
时间:
2014-12-17 21:09
标题:
迟来的基础测试,好在赶上了末班车。
计划是要去50期的,奈何琐事缠身,0基础学习起来也没想象那么顺利。
好在年前还能拼一拼,不想等到年后了。
贴上一篇做了两天的基础测试boss题。
package com.itheima;
import java.util.LinkedList;
/**
* 第10题 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。 当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,
* 则不会发生这种问题。编程解决猫狗鱼过河问题。
*
* @author always
*
* 思路:用面向对象的思维思考问题,猫、狗、鱼、老农、都是对象,河此岸和对岸分别是两个可容纳对象的集合。 赋予对象本身属性:位置变量,
* 判断是否可以过河的方法; 步骤:
* 1.创建猫狗鱼老农对象,赋予对象位置变量loc和判断是否可以过河的方法canCross()在主函数中初始化对象
* 2.创建两个集合,分别用于河此岸和对岸,把4个对象装入此岸集合中
* 3.通过判断此岸集合是否为空进行循环,每次循环判断老农在哪个集合中,进行过河
* 4.过河过程中,老农优先自己过河,前提是前一次不是老农自己过河并且老能可以自己过河(老农对象自身会根据条件进行判断是否可以过河)
* 5.如果无法自己过河,则老农带一只动物过河,每次过河有两个条件,1.过河者本身判定可以过河2.这次过河这跟上次不能相同(避免死循环)
* 6.过程中在控制台输出过河细节,便于查看代码运行流程。
*
*/
public class Test10 {
/**
* 要过河的对象引用
*
* @param dog
* @param cat
* @param fish
* @param farmer
*/
@SuppressWarnings("unused")
private static Element dog, cat, fish, farmer;
/**
* 当前过河者, 如果是老农带着动物过河,则过河者是动物;如果是老农自己过河,则过河者是老农
*/
private static Element currentCrosser;
/**
* 上一次过河者 如果是老农带着动物过河,则过河者是动物;如果是老农自己过河,则过河者是老农
*/
private static Element lastCrosser;
// 河此岸,LinkedList增删快,而频繁的过河需要不断的增删元素,所以选择LinkeList
private static LinkedList<Element> thisBank;
// 河对岸集合
private static LinkedList<Element> otherBank;
public static void main(String[] args) {
// 元素变量初始化赋值
dog = Element.DOG;
cat = Element.CAT;
fish = Element.FISH;
farmer = Element.FARMER;
// 集合初始化
thisBank = new LinkedList<Element>();
otherBank = new LinkedList<Element>();
// 初始化老人和动物对象到thisBank集合中
for (int i = 0; i < 4; i++) {
thisBank.add(Element.values()[i]);
}
// 开始过河
System.out.println("初始化:\n\t此岸: " + thisBank + "\n\t对岸:" + otherBank);
// 定义在循环外的字符串变量
String thisBankName = "此岸";
String otherBankName = "对岸";
while (!thisBank.isEmpty()) { // 只要thisBank集合不为空,就说明没有过河成功
if (thisBank.contains(farmer)) {
crossRiver(thisBank, otherBank); // 从此岸过河到对岸
show(thisBankName, otherBankName);
} else {
crossRiver(otherBank, thisBank); // 从对岸回到此岸
show(otherBankName, thisBankName);
}
}
System.out.println("老农成功带着动物们过河到对岸!");
}
/**
* 演示过河流程
*
* @param fromBankName
* 出发地的名字
* @param toBankname
* 目的地的名字
*/
private static void show(String fromBankName, String toBankname) {
if (lastCrosser.equals(farmer))
System.out.println("老农自己到" + toBankname + "\n\t此岸: " + thisBank
+ "\n\t对岸:" + otherBank);
else
System.out.println("老农带着" + lastCrosser + "到" + toBankname
+ "\n\t此岸: " + thisBank + "\n\t对岸:" + otherBank);
}
/**
* 过河功能封装
*
* @param thisBank
* 从哪一岸出发
* @param otherBank
* 要到哪去
*/
private static void crossRiver(LinkedList<Element> thisBank,
LinkedList<Element> otherBank) {
currentCrosser = null; // 初始化当前过河者为null
for (Element el : thisBank) { // 遍历出发地集合中的对象
// 设定优先级,如果老农可以自己过河(farmer.canCrose()),并且上一次过河的不是老农自己,那么就优先老农自己过河
if (farmer.canCrose() && lastCrosser != farmer) {
act(thisBank, otherBank, farmer);
lastCrosser = farmer;
break;
}
// 如果哪只动物可以过河,并且不是上一次过河者,则让其过河
if (el.canCrose() && el != lastCrosser) {
currentCrosser = el; // 设置el为当前过河者
break;
}
}
if (currentCrosser != null) { // 如果老农不是一个人在过河
act(thisBank, otherBank, farmer); // 老农过河
act(thisBank, otherBank, currentCrosser); // 当前过河者过河
lastCrosser = currentCrosser; // 设置el为上一次过河者
}
}
/**
* 过河核心功能封装
*
* @param fromBank
* 从哪一岸出发
* @param toBank
* 要到哪去
* @param crosser
* 过河者
*/
private static void act(LinkedList<Element> fromBank,
LinkedList<Element> toBank, Element crosser) {
fromBank.remove(crosser); // 此岸集合删除元素
toBank.add(crosser); // 对岸集合增加元素
crosser.chanceLoc(); // 过河者改变自身位置
}
/**
* 枚举类,分别定义元素狗、猫,鱼与老农,并初始化他们的位置为此岸(true)。
*
* @author always
*
*/
public enum Element {
/**
* 狗对象, 初始化位置loc为true
*/
DOG(true) {
@Override
boolean canCrose() {
return CAT.loc != FISH.loc;
}
},
/**
* 猫对象, 初始化位置loc为true
*/
CAT(true) {
@Override
boolean canCrose() {
return true;
}
},
/**
* 鱼对象, 初始化位置loc为true
*/
FISH(true) {
@Override
boolean canCrose() {
return DOG.loc != CAT.loc;
}
},
/**
* 老农对象, 初始化位置loc为true
*/
FARMER(true) {
/**
* 老农过河的条件:狗和猫不能在一起 并且猫和鱼不能在一起
*/
@Override
boolean canCrose() {
return DOG.loc != CAT.loc && CAT.loc != FISH.loc;
}
};
/**
* 定义位置变量
*
* @param loc
* 位置, true为河此岸,false为河对岸
*/
private boolean loc;
/**
* 构造方法,用于初始化元素所在的位置
*
* @param loc
* 位置, true为河此岸,false为河对岸
*/
private Element(boolean loc) {
this.loc = loc;
}
/**
* 改变对象所在的河岸,loc如果是true 则改成false, 如果是false 则改成true
*
* @param loc
* this.loc
*/
public void chanceLoc() {
loc = loc ? false : true;
}
/**
* 对象是否可以过河,老农要带着狗过河,必须确定猫和鱼不在一起 如果带鱼过河,必须确定狗和猫不在一起
* 而每个对象是否可以过河是有对象的自身属性决定的,所以每个元素都必须实现这个抽象方法
*
* @return true可以过河, false 不可以过河
*/
abstract boolean canCrose();
}
}
复制代码
作者:
jxlovqqvo
时间:
2014-12-17 21:36
这个过河问题有这么复杂么:L
作者:
sean
时间:
2014-12-17 21:48
题目很经典,但是代码已经看晕了。
作者:
qq8921310
时间:
2014-12-17 22:18
写的太复杂了
作者:
fatesabering
时间:
2014-12-17 22:20
好长的代码 这是基础测试?
作者:
董晗
时间:
2014-12-17 22:22
好多代码啊
作者:
zcyemenye
时间:
2014-12-17 22:25
{:3_55:}大神。。。给跪了
作者:
Jason996
时间:
2014-12-17 22:32
这个基础测试也太难了吧
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2