计划是要去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();
- }
- }
复制代码 |