1 貓,狗,魚過河問題
有一條河,河上沒有橋,一個農夫帶着一隻狗,一隻貓,一條魚過河
農夫發現岸邊有一天船
這個船一次只能裝載農夫和任意一種東西過河
當農夫從左岸划船到右岸時,如果農夫離開了其中的一邊,另一邊可能會發生問題:
貓和狗在一起,狗咬貓
貓和魚在一起,貓咬魚
編程解上述問題
分析:
通過分析,河的存在性不重要,需要設計左岸和右岸,整個問題的最終目標:把三個動物從左邊帶到右邊
左岸和右岸描述動物現在待得地方
設計容器A,表示左邊,設計容器B,表示右邊
數組:缺點,獲取數組中已有的元素數量非常不方便
集合:優點,獲取數組中已有的元素數量非常方便
所以,使用集合
船是綁定着河和這個題目出現的一個模型,所以不需要
人:起的作用僅僅是爲了人所在的岸邊不會出現問題,所以人要麼在左邊,要麼在右邊,所以使用boolean型
設計一個boolean值描述人在哪一邊,當人在左邊,只需要檢測右邊的矛盾關係
貓狗魚:
特點:任意一個動物都可能和另一種動物發生矛盾
貓狗魚之間存在着一種制約關係,可以通過一個類的幾個屬性描述這種關係
程序執行過程中的問題
1.帶過去動物後,發現出現問題,需要回退
//設計一種模型,保存移動前的狀態,當移動後出現問題,迴歸之前的狀態
2.移動過程中,考慮當前移動的操作是否曾經出現過,如果出現過
//設計一種模型,用於描述曾經出現過的所有的移動狀態
//設計一種模型,保存之前所有移動的狀態,每次移動都要保存
import java.util.ArrayList;
class CrossRiver{
//河左岸
private ArrayList<Animal> left = new ArrayList<Animal>();
//河右岸
private ArrayList<Animal> right = new ArrayList<Animal>();
//人在左邊是true,在右邊是false
private boolean flag = true;
//定義一個方法,用於執行當前的過河操作
void crossRiver(){
//1.初始化三個動物
initAnimal();
//2.開始執行過河操作
//設計一個循環
while(right.size() != 3){
//1.首先檢測人在那邊
//1.1人在左,左邊發生移動操作,
//1.2人在右,右邊發生移動操作
if(flag){
//移動left->right
move();
}else{
//移動right->left
move();
}
}
}
//移動操作
void move(){
//從一個集合中刪除一個數據,將這個數據添加到另一個集合中
//這裏還需要考慮人單獨移動的情況
//這裏就實現了一個移動操作
Object obj = left.remove(1);//刪除
right.add((Animal) obj);
//人的位置要變化
flag = !flag;
//移動後一定要檢測是否出現問題
//檢測哪邊?
//flag = true ;// 左
//flag = false; //右
//開始檢測:人不再一邊,動物數量超過1個就檢測
// 人在右邊,左邊集合中只有一個元素,右邊集合中有兩個元素//不檢測
// 人在右邊,左邊集合中有兩個元素或者三個元素,檢測
}
//初始化動物
//1是狗,2是貓,3是魚
void initAnimal(){
//創建三個動物,並且添加到左岸
Animal cat = new Animal();
cat.afraid = 1;
cat.control = 2;
left.add(cat);
//按照上面的格式,將三個動物都添加到河左岸
Animal dog = new Animal();
dog.afraid = -1;
dog.control = 1;
left.add(dog);
Animal fish = new Animal();
fish.afraid = 2;
fish.control = 3;
left.add(fish);
}
public static void main(String[] args){
}
}
class Animal{
//有一被制約
int afraid;
//有一制約
int control;
//設計一個制約關係
boolean check(Animal a){
/*
if(this.afraid == a.control || a.afraid == this.control){
//出現了不和諧的現象
return true;
}else{
return false;
}
*/
return this.afraid == a.control || a.afraid == this.control;
}
}