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

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就指向哪个List
			hereOrThere = 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);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值