A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© noiary 高级黑马   /  2014-12-17 21:09  /  1073 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

计划是要去50期的,奈何琐事缠身,0基础学习起来也没想象那么顺利。

好在年前还能拼一拼,不想等到年后了。

贴上一篇做了两天的基础测试boss题。

  1. package com.itheima;

  2. import java.util.LinkedList;

  3. /**
  4. * 第10题 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。 当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,
  5. * 则不会发生这种问题。编程解决猫狗鱼过河问题。
  6. *
  7. * @author always
  8. *
  9. *         思路:用面向对象的思维思考问题,猫、狗、鱼、老农、都是对象,河此岸和对岸分别是两个可容纳对象的集合。 赋予对象本身属性:位置变量,
  10. *         判断是否可以过河的方法; 步骤:
  11. *         1.创建猫狗鱼老农对象,赋予对象位置变量loc和判断是否可以过河的方法canCross()在主函数中初始化对象
  12. *         2.创建两个集合,分别用于河此岸和对岸,把4个对象装入此岸集合中
  13. *         3.通过判断此岸集合是否为空进行循环,每次循环判断老农在哪个集合中,进行过河
  14. *         4.过河过程中,老农优先自己过河,前提是前一次不是老农自己过河并且老能可以自己过河(老农对象自身会根据条件进行判断是否可以过河)
  15. *         5.如果无法自己过河,则老农带一只动物过河,每次过河有两个条件,1.过河者本身判定可以过河2.这次过河这跟上次不能相同(避免死循环)
  16. *         6.过程中在控制台输出过河细节,便于查看代码运行流程。
  17. *
  18. */

  19. public class Test10 {

  20.         /**
  21.          * 要过河的对象引用
  22.          *
  23.          * @param dog
  24.          * @param cat
  25.          * @param fish
  26.          * @param farmer
  27.          */
  28.         @SuppressWarnings("unused")
  29.         private static Element dog, cat, fish, farmer;

  30.         /**
  31.          * 当前过河者, 如果是老农带着动物过河,则过河者是动物;如果是老农自己过河,则过河者是老农
  32.          */
  33.         private static Element currentCrosser;

  34.         /**
  35.          * 上一次过河者 如果是老农带着动物过河,则过河者是动物;如果是老农自己过河,则过河者是老农
  36.          */
  37.         private static Element lastCrosser;

  38.         // 河此岸,LinkedList增删快,而频繁的过河需要不断的增删元素,所以选择LinkeList
  39.         private static LinkedList<Element> thisBank;

  40.         // 河对岸集合
  41.         private static LinkedList<Element> otherBank;

  42.         public static void main(String[] args) {

  43.                 // 元素变量初始化赋值
  44.                 dog = Element.DOG;
  45.                 cat = Element.CAT;
  46.                 fish = Element.FISH;
  47.                 farmer = Element.FARMER;

  48.                 // 集合初始化
  49.                 thisBank = new LinkedList<Element>();
  50.                 otherBank = new LinkedList<Element>();

  51.                 // 初始化老人和动物对象到thisBank集合中
  52.                 for (int i = 0; i < 4; i++) {
  53.                         thisBank.add(Element.values()[i]);
  54.                 }

  55.                 // 开始过河
  56.                 System.out.println("初始化:\n\t此岸: " + thisBank + "\n\t对岸:" + otherBank);

  57.                 // 定义在循环外的字符串变量
  58.                 String thisBankName = "此岸";
  59.                 String otherBankName = "对岸";

  60.                 while (!thisBank.isEmpty()) { // 只要thisBank集合不为空,就说明没有过河成功
  61.                         if (thisBank.contains(farmer)) {
  62.                                 crossRiver(thisBank, otherBank); // 从此岸过河到对岸
  63.                                 show(thisBankName, otherBankName);
  64.                         } else {
  65.                                 crossRiver(otherBank, thisBank); // 从对岸回到此岸
  66.                                 show(otherBankName, thisBankName);
  67.                         }
  68.                 }

  69.                 System.out.println("老农成功带着动物们过河到对岸!");
  70.         }

  71.         /**
  72.          * 演示过河流程
  73.          *
  74.          * @param fromBankName
  75.          *            出发地的名字
  76.          * @param toBankname
  77.          *            目的地的名字
  78.          */
  79.         private static void show(String fromBankName, String toBankname) {
  80.                 if (lastCrosser.equals(farmer))
  81.                         System.out.println("老农自己到" + toBankname + "\n\t此岸: " + thisBank
  82.                                         + "\n\t对岸:" + otherBank);
  83.                 else
  84.                         System.out.println("老农带着" + lastCrosser + "到" + toBankname
  85.                                         + "\n\t此岸: " + thisBank + "\n\t对岸:" + otherBank);
  86.         }

  87.         /**
  88.          * 过河功能封装
  89.          *
  90.          * @param thisBank
  91.          *            从哪一岸出发
  92.          * @param otherBank
  93.          *            要到哪去
  94.          */
  95.         private static void crossRiver(LinkedList<Element> thisBank,
  96.                         LinkedList<Element> otherBank) {

  97.                 currentCrosser = null; // 初始化当前过河者为null

  98.                 for (Element el : thisBank) { // 遍历出发地集合中的对象
  99.                         // 设定优先级,如果老农可以自己过河(farmer.canCrose()),并且上一次过河的不是老农自己,那么就优先老农自己过河
  100.                         if (farmer.canCrose() && lastCrosser != farmer) {
  101.                                 act(thisBank, otherBank, farmer);
  102.                                 lastCrosser = farmer;
  103.                                 break;
  104.                         }

  105.                         // 如果哪只动物可以过河,并且不是上一次过河者,则让其过河
  106.                         if (el.canCrose() && el != lastCrosser) {
  107.                                 currentCrosser = el; // 设置el为当前过河者
  108.                                 break;
  109.                         }
  110.                 }
  111.                 if (currentCrosser != null) { // 如果老农不是一个人在过河
  112.                         act(thisBank, otherBank, farmer); // 老农过河
  113.                         act(thisBank, otherBank, currentCrosser); // 当前过河者过河
  114.                         lastCrosser = currentCrosser; // 设置el为上一次过河者
  115.                 }

  116.         }

  117.         /**
  118.          * 过河核心功能封装
  119.          *
  120.          * @param fromBank
  121.          *            从哪一岸出发
  122.          * @param toBank
  123.          *            要到哪去
  124.          * @param crosser
  125.          *            过河者
  126.          */
  127.         private static void act(LinkedList<Element> fromBank,
  128.                         LinkedList<Element> toBank, Element crosser) {
  129.                 fromBank.remove(crosser); // 此岸集合删除元素
  130.                 toBank.add(crosser); // 对岸集合增加元素
  131.                 crosser.chanceLoc(); // 过河者改变自身位置

  132.         }

  133.         /**
  134.          * 枚举类,分别定义元素狗、猫,鱼与老农,并初始化他们的位置为此岸(true)。
  135.          *
  136.          * @author always
  137.          *
  138.          */
  139.         public enum Element {

  140.                 /**
  141.                  * 狗对象, 初始化位置loc为true
  142.                  */
  143.                 DOG(true) {
  144.                         @Override
  145.                         boolean canCrose() {
  146.                                 return CAT.loc != FISH.loc;
  147.                         }
  148.                 },

  149.                 /**
  150.                  * 猫对象, 初始化位置loc为true
  151.                  */
  152.                 CAT(true) {
  153.                         @Override
  154.                         boolean canCrose() {
  155.                                 return true;
  156.                         }
  157.                 },

  158.                 /**
  159.                  * 鱼对象, 初始化位置loc为true
  160.                  */
  161.                 FISH(true) {
  162.                         @Override
  163.                         boolean canCrose() {
  164.                                 return DOG.loc != CAT.loc;
  165.                         }
  166.                 },

  167.                 /**
  168.                  * 老农对象, 初始化位置loc为true
  169.                  */
  170.                 FARMER(true) {
  171.                         /**
  172.                          * 老农过河的条件:狗和猫不能在一起 并且猫和鱼不能在一起
  173.                          */
  174.                         @Override
  175.                         boolean canCrose() {
  176.                                 return DOG.loc != CAT.loc && CAT.loc != FISH.loc;
  177.                         }
  178.                 };

  179.                 /**
  180.                  * 定义位置变量
  181.                  *
  182.                  * @param loc
  183.                  *            位置, true为河此岸,false为河对岸
  184.                  */
  185.                 private boolean loc;

  186.                 /**
  187.                  * 构造方法,用于初始化元素所在的位置
  188.                  *
  189.                  * @param loc
  190.                  *            位置, true为河此岸,false为河对岸
  191.                  */
  192.                 private Element(boolean loc) {
  193.                         this.loc = loc;
  194.                 }

  195.                 /**
  196.                  * 改变对象所在的河岸,loc如果是true 则改成false, 如果是false 则改成true
  197.                  *
  198.                  * @param loc
  199.                  *            this.loc
  200.                  */
  201.                 public void chanceLoc() {
  202.                         loc = loc ? false : true;
  203.                 }

  204.                 /**
  205.                  * 对象是否可以过河,老农要带着狗过河,必须确定猫和鱼不在一起 如果带鱼过河,必须确定狗和猫不在一起
  206.                  * 而每个对象是否可以过河是有对象的自身属性决定的,所以每个元素都必须实现这个抽象方法
  207.                  *
  208.                  * @return true可以过河, false 不可以过河
  209.                  */
  210.                 abstract boolean canCrose();
  211.         }
  212. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1

查看全部评分

7 个回复

倒序浏览
这个过河问题有这么复杂么:L
回复 使用道具 举报
题目很经典,但是代码已经看晕了。
回复 使用道具 举报
写的太复杂了
回复 使用道具 举报
好长的代码 这是基础测试?
回复 使用道具 举报
好多代码啊
回复 使用道具 举报
{:3_55:}大神。。。给跪了
回复 使用道具 举报
这个基础测试也太难了吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马