[code]package com.itheima;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/*
* 题目10:10、 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。
* 当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。
* 编程解决猫狗鱼过河问题。
*
* 分析思路: 在纸上分析过后得知要像将猫、狗、鱼安全的送往河对岸,可使用下述步骤:
* 第一步:将猫先运到河对岸 ,放下猫农夫和船回来; ====> 已过河: 猫
* 第二步:将狗装上船运到河对岸,并且将猫带回放下; ====> 已过河: 狗
* 第三步:将鱼运过对岸放下,农夫空船回来; ====> 已过河: 狗、鱼
* 第四步:农夫将猫再次运到河对岸。 ====> 已过河: 狗、鱼、猫
*/
public class Test10 {
// 1:因为数据长度频繁的改变所以,用集合来装数据。并且将河的两边比喻为两个不同的集合
// left :表示左边的河岸 right:表示右边的河岸也就是对岸。
List<String> left = new ArrayList<String>();
List<String> right = new ArrayList<String>();
// 2:因为一开始河的左岸就是有人和三个动物的,所以程序一加载就应该添加他们
public Test10() {
left.add("farmers");
left.add("cat");
left.add("dog");
left.add("fish");
}
public static void main(String[] args) {
// 调用过河方法
Test10 test = new Test10();
/*for (String string : test.left) {
System.out.println(string);
}*/
test.passRiver();
}
// 过河的方法
public void passRiver() {
do {
// 首先农夫上船
left.remove("farmers");
// 接着农夫随便的带上一只动物上船,利用脚标取值,脚标随机并且在[1,4)之间,对应 cat、dog、fish
// 产生随机数,可以使用Random类中的nextInt(int num);方法产生一个在[0,num)之间的数
int leftIndex = new Random().nextInt(left.size()); /*IllegalArgumentException:抛出的异常表明向方法传递了一个不合法或不正确的参数。*/
// 取得脚标所对应的动物,并装上船
String animal = left.get(leftIndex); /*IndexOutOfBoundsException:脚标越界*/
//判断农夫现在带走的动物是否是上一次带回来的动物(因为每次都会自动的添加到最后一个)
if (left.size()>1 && animal.equals(left.get(left.size()-1))) {
left.add("farmers");
//跳出当前循环,进入下一个循环
continue;
}
left.remove(animal);
// 此时left的岸边只有两个动物了,并且我们不确定这两个其中是否有猫,所以得判断
if (isSafe(left)) {
// 将左边的动物带到河对岸。
right.add(animal);
System.out.println("恭喜农夫和"+"\'"+animal+"\'"+"成功渡河!");
// 此时如果河对岸有3个动物,并且不包括农夫的话就算过河都成功返回
if (right.size() == 3 && !right.contains("farmers")) {
System.out.println("恭喜狗、猫、鱼渡河成功!!!");
break;
}
// 此时农夫准备返航回去,那么就得判断农夫离开后河对岸(right)是否安全
// 但是如果对岸只有一个动物的话就没有必要判断了
if (right.size() != 1) {
if (isSafe(right)) {
left.add("farmers");
System.out.println("农夫独自返航了!");
} else {
// 获取对岸动物的脚标
int rightIndex = new Random().nextInt(right.size());
// 获取脚标对应的动物名
String animal2 = right.get(rightIndex);
// 如果不安全,则要带回一个动物,但是不能是前一次带过来的动物。
while (animal2.equals(animal)) {
animal2 = right.get(rightIndex);
}
//将非上一次带过来的动物从对岸带回
right.remove(animal2);
left.add(animal2);
System.out.println("农夫和" + "\'" + animal2 + "\'回来了");
}
} else {
left.add("farmers");
System.out.println("农夫独自返航了!");
}
} else {
// left岸边的动物们不安全,把带上的动物放下换一个
left.add("farmers");
left.add(animal);
}
} while (left.size() != 0);
}
// 判断是否安全的方法,返回的是boolean类型的值
private static Boolean isSafe(List<String> list) {
// 定义一个变量用来接收返回的值
Boolean flag;
// 判断两边岸的动物是否安全的依据是看猫和农夫是否在一起,如果农夫和猫不在一起并且猫和其他的动物在一起,则河岸不安全。
if (list.size() > 1 && list.contains("cat") && list.contains("cat")
|| list.contains("cat") && list.contains("fish")) {
flag = false;
} else {
flag = true;
}
return flag;
}
}
[/code]
|