老农猫、狗、鱼过河问题 黑马测试题,个人的解答.靠程序搜索答案 只给判断条件,无人为辅助判断

来源:互联网 发布:下载贵金属软件 编辑:程序博客网 时间:2024/05/21 04:36
package com.itheima;import java.util.ArrayList;import java.util.List;/** * 第10题: 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时, * 则不会发生这种问题。编程解决猫狗鱼过河问题。 *  *  答: *  ...这类型的题目没接触过,刚开始没有头绪,在草稿纸上画了几页图找出了方法,奋战多个小时,又花了大半个小时写注释...写出来后有点小开心额 呵呵~_~  *  我的算法的思路是这样的:  *  用两个List容纳各种动物,分别表示同一时刻在起点和终点 * 都有哪些动物 判断是否冲突的方法是 用两个List(dogAndCat和fishAndCat)容纳数据 一个只包含狗和猫 一个只包含猫和鱼 然后通过 * Collection.containsAll(dogAndCat或fishAndCat)的值为true或者false来判断起点或者终点有没有冲突的动物 * 用一个isHere变量来指示农夫的位置是在起点还是终点 用hereOrThere List引用变量 来指向当前位置(起点或终点)的List *  * 流程是:  * 农夫有携带着动物的话, 就先把动物放在当前位置 (add到List中)  * 判断放下该动物后 终点是否所有动物都到齐了 是就结束程序了 *  * 否则继续执行下面的 判断:  * 如果在终点 并且终点的动物不存在冲突 那么不携带任何动物 空手折返 * 否则就拿起一个动物(通过方法判断余下的动物是否存在冲突并返回应该拿起的动物)再折返 循环搜索 直到 所有动物安全聚集在终点 *  * @author : WingsZheng * @time : 2014年8月18日上午2:44:51 */public class Test10 {// 该List用于表示同时存在狗和猫的情况private static List<String> dogAndCat = new ArrayList<String>();// 该List用于表示同时存在猫和鱼的情况private static List<String> fishAndCat = new ArrayList<String>();// 该List用于表示同时存在所有动物的情况private static List<String> allAnimal = new ArrayList<String>();// 该布尔变量用于判断是农夫当前在起点还是终点,设为全局变量,是用于在拿起和放下的方法中根据该变量的值,打印输出内容private static boolean isHere = true;// 静态初始化3个List 这3个List 配合 List.containsAll()方法来 判断是否存在冲突static {dogAndCat.add("dog");dogAndCat.add("cat");fishAndCat.add("fish");fishAndCat.add("cat");allAnimal.add("dog");allAnimal.add("cat");allAnimal.add("fish");}public static void main(String[] args) {// 用于容纳起点的动物List<String> here = allAnimal;// 用于容纳终点的动物List<String> there = new ArrayList<String>();// 这个变量用来标记正在被农夫携带的动物->即拿起的动物String getAnimal = null;// 这个引用变量用于指向当前操作的位置 here 或者 there;List<String> hereOrThere;// 在一个死循环中搜索各种方案,直到终点容纳所有动物后退出循环while (true) {// 根据isHere为true或false,hereOrThere就指向哪个ListhereOrThere = isHere ? here : there;// 在当前位置放下动物 如果当前没有携带动物,即getAnimal为null,该方法不会执行任何操作dropAnimal(getAnimal, hereOrThere);// 如果所有动物都在终点了,则表示成功,退出死循环// !isHere表示 如果当前操作位置在起点就无需判断终点是否包含所有动物if (!isHere && there.containsAll(allAnimal))break;// 没有成功则继续执行下面的操作// 判断当前操作的位置(起点或终点) 是否存在 动物之间的冲突// isSomeAnimalwillBeDead方法返回true就表示冲突false就表示不冲突if (!isSomeAnimalwillBeDead(hereOrThere) && !isHere) {// 如果不存在冲突 并且 在终点 则不拿起动物 农夫空手折返getAnimal = null;} else {// 否则 拿起一个正确的动物 (拿起后留下来的动物不会冲突)getAnimal = getCorrectAnimal(getAnimal, hereOrThere);}// 切换位置 表示农夫来回 如果在起点就切换到终点,反之亦然isHere = !isHere;}}/** *  * @param getAnimal *            表示该操作放下的动物,由农夫当前携带的动物决定 * @param hereOrThere *            当前位置 void */private static void dropAnimal(String getAnimal, List<String> hereOrThere) {// 如果animal为空则没有任何动物被放下if (getAnimal != null) {hereOrThere.add(getAnimal);//打印当前操作System.out.println((isHere ? "在起点" : "在终点") + "放下:" + getAnimal);}}/** * 拿起正确的动物,正确的动物指的是 拿起该动物后 剩余的动物不存在冲突 *  * @param justPutDown *            该参数传入刚刚放下的动物 , 用于过滤掉当前动物, 避免同一动物来回携带,造成死循环 * @param hereOrThere *            传入当前位置的List * @return 返回 正确的动物,拿起该动物 剩余的动物不存在冲突 String */private static String getCorrectAnimal(String justPutDown,List<String> hereOrThere) {// 如果传入的刚放下的动物为null,则随意赋值 以免在下面进行equals判断时发生空指针异常if (justPutDown == null)justPutDown = "NoAnimal";// 用临时变量保存List,防止在下面的循环中增删操作引起索引混乱List<String> temp = new ArrayList<String>();for (String string : hereOrThere) {temp.add(string);}// result变量用于保存当前选定的动物,最终判断无冲突后以该值作为返回值String result = null;for (int i = 0; i < temp.size(); i++) {result = temp.get(i);// 过滤掉刚放下的动物,以免陷入死循环if (!justPutDown.equals(result)) {// 从当前位置删除该动物 即表示农夫拿起该动物hereOrThere.remove(result);// 判断拿起该动物后,剩余的动物是否存在冲突 (是否有些动物会死)if (isSomeAnimalwillBeDead(hereOrThere)) {// 冲突则 执行恢复操作,把拿起的动物重新放下hereOrThere.add(result);continue;} else {// 不冲突则直接退出循环 把该动物当做返回值break;}}}// 打印当前操作System.out.println((isHere ? "从起点" : "从终点") + "拿起:" + result);return result;}/** * 根据当前位置的List是否包含所有dogAndCat或者fishAndCat 来判断是否存在冲突情况 *  * @param hereOrThere *            当前位置的List * @return 是否存在冲突 true表示冲突 false表示不冲突 Boolean */private static Boolean isSomeAnimalwillBeDead(List<String> hereOrThere) {return hereOrThere.containsAll(dogAndCat)|| hereOrThere.containsAll(fishAndCat);}}

0 0
原创粉丝点击