让标题:农民希望猫左岸用船、狗、鱼运至右岸。

在运输过程中,每次只能运送一个单纯的动物。过河农民可以空船。

当中当人不在此岸时,狗会咬猫。猫会吃鱼。当人在此岸时,则不会发生冲突。

请用面向对象的设计思想解决此类问题。

分析:通过题设条件能够得出下面结论:1、左到右,不存在从左岸到右岸的空船(也就是从左岸到右岸必须运送一仅仅动物);2、右到左。有且仅仅有两种情况:①空船过河、②带一仅仅动物过河。

程序设计:5个类:MyCrossRiver.java、CrossProcess.java、CrossStep.java、Status.java、Animal.java。当中。MyCrossRiver是程序执行的主类,也包括了过河逻辑;CrossProsess是记录整个过程已经走过的正确的步骤序列;CrossStep表示的是所走过的每一步;Status表示的是对当前步骤的状态的封装(对于左岸和右岸的数据是深度拷贝);Animal是动物的抽象。

主要代码例如以下:

MyCrossRiver.java:

package com.others;import java.util.ArrayList;
import java.util.List;/*** 猫狗鱼过河问题* @author xuefeihu**/
public class MyCrossRiver {/** 河左岸 **/private List<Animal> left = new ArrayList<Animal>();/** 河右岸 **/private List<Animal> right = new ArrayList<Animal>();/** 人的位置:左边是true,右边是false **/private boolean flag = true;/** 过河步骤 **/private CrossProcess process = new CrossProcess();public static void main(String[] args) {new MyCrossRiver().crossRiver();}/*** 初始化条件*/public void initAnimal(){Animal dog = new Animal("狗", 1, -1, 2);Animal cat = new Animal("猫", 2, 1, 3);Animal fish = new Animal("鱼", 3, 2, -1);left.add(dog);left.add(cat);left.add(fish);}/*** 过河操作*/public void crossRiver(){initAnimal();while(right.size() != 3){Status preStatus = new Status(this.left, this.right, this.flag);//记录步骤前状态CrossStep step = new CrossStep(process.getStepCount()+1, this.flag, null, preStatus);//创建步骤if(this.flag){//从左到右过河(不存在空船过河)int leftIndex = step.getNextLeftIndex();int leftSize = this.left.size();if(leftIndex >= leftSize){//回退数据this.process.removeLastStep();CrossStep step2 = this.process.getLastStep();this.back2Step(step2);continue;}else{//带动物过河step.setAnimal(this.left.get(leftIndex));}}else{//从右往左过河Animal animal = null;boolean rightSecurity = this.check(right);if(rightSecurity){animal = this.getTargetAnimal(this.right);if(animal == null){//冲突无法解决时,回退数据this.process.removeLastStep();CrossStep step2 = this.process.getLastStep();this.back2Step(step2);continue;}else{step.setAnimal(animal);}}else{//无冲突时。不运送动物step.setAnimal(null);}}boolean result = moveByOneStep(step);if(!result){//假设运行失败,则恢复上一步骤this.process.removeLastStep();CrossStep step2 = this.process.getLastStep();this.back2Step(step2);}}this.process.printStepMessage();}/*** 移动操作* @param step* @return 返回true表示转移成功,false表示转移失败(失败时须要回退到上一步进行转移)*/public boolean moveByOneStep(CrossStep step){/** 返回的结果:true表示移动成功、false表示失败 **/boolean result = false;/** 循环标志位 **/boolean cricleFlag = false;while(!cricleFlag){int leftIndex = step.getNextLeftIndex();int leftSize = step.getStatus().getLeft().size();int rightIndex = step.getNextRightIndex();if(this.flag){//当能够找到下一个索引时,进行转移if(leftIndex < leftSize){//带动物过河Animal animal = left.remove(leftIndex);right.add(animal);flag = !flag;step.setAnimal(animal);}else if(leftIndex >= leftSize){return false;//返回失败信息,并交给上一层程序处理}}else if(!this.flag){if(step.getAnimal() == null){//此时能够单人过河flag = !flag;this.process.addStep(step);return true;}else{//带动物过河Animal animal = right.remove(rightIndex);left.add(animal);flag = !flag;}}//检查冲突情况(转移后回退)if(!this.flag && check(this.left)){step.addNextLeftIndex();this.back2Step(step);}else if(this.flag && check(this.right)){step.addNextRightIndex();this.back2Step(step);}else {this.process.addStep(step);result = true;cricleFlag = true;}}return result;}/*** 将当前状态恢复到step步骤* @param step*/private void back2Step(CrossStep step){Status status = step.getStatus();this.left = status.getLeft();this.right = status.getRight();this.flag = status.getFlag();}/*** 从冲突的数据中获取不冲突的动物:不存在时返回null*/public Animal getTargetAnimal(List<Animal> array){Animal result = null;//克隆对象List<Animal> lists = new ArrayList<Animal>();Animal target = null;Animal source = null;for(int i = 0; i < array.size(); i++){source = array.get(i);target = new Animal(source.type, source.id, source.afraid, source.control);lists.add(target);}//查找对象for(int i = 0; i < lists.size(); i++){result = lists.remove(i);if(!check(lists)){break;}lists.add(i, result);}return result;}/*** 检查是否有冲突*/private boolean check(List<Animal> array){boolean result = true;if(array.size() > 1){for(int i = 0; i < array.size(); i++){for(int j = i+1; j < array.size(); j++){result = array.get(i).check(array.get(j));if(result) return result;}}}else{result = false;}return result;}}

CrossProcess.java

package com.others;import java.util.ArrayList;
import java.util.List;/*** 过河的过程* @author xuefeihu**/
public class CrossProcess {/** 全部步骤 **/private List<CrossStep> steps = new ArrayList<CrossStep>();/*** 加入步骤* @param step 步骤*/public void addStep(CrossStep step){if(step.getDirection()){step.addNextLeftIndex();}else{step.addNextRightIndex();}this.steps.add(step);}/*** 删除最后一步*/public CrossStep removeLastStep(){return this.steps.remove(this.steps.size()-1);}/*** 获取最后一个步骤* @return*/public CrossStep getLastStep(){return this.steps.get(this.steps.size()-1);}/*** 打印步骤信息*/public void printStepMessage(){for(CrossStep step : steps){System.out.println(step.getMessage());}}/*** 获得当前步骤数* @return*/public int getStepCount(){return this.steps.size();}}

CrossStep.java

package com.sunrise.others;
/*** 过河步骤* @author xuefeihu**/
public class CrossStep {/** 步骤数 **/private int stepCount;/** 方向:true是左到右,false是右到左 **/private boolean direction;/** 此步骤运送的动物 **/private Animal animal;/** 该步骤之前状态 **/private Status status;/** 打印语句 **/private String message;/** 下一个左側须要移动的索引 **/private int nextLeftIndex = 0;/** 下一个右側须要移动的索引 **/private int nextRightIndex = 0;/*** 构造器* @param stepCount 步骤数* @param direction 方向:true是左到右,false是右到左* @param animal 此步骤运送的动物* @param status 当前状态*/public CrossStep(int stepCount, boolean direction, Animal animal, Status status) {this.stepCount = stepCount;this.direction = direction;this.animal = animal;this.status = status;this.message = "第"+stepCount+"步:农夫将" + (this.animal==null?" 自己 ":this.animal.type) + (this.direction ? "从左岸运到右岸" : "从右岸运到左岸");}public int getStepCount() {return stepCount;}public boolean getDirection() {return direction;}public Animal getAnimal() {return animal;}public Status getStatus() {return status;}public String getMessage() {return message;}public int getNextLeftIndex() {return nextLeftIndex;}public void addNextLeftIndex() {this.nextLeftIndex++;}public int getNextRightIndex() {return nextRightIndex;}public void addNextRightIndex() {this.nextRightIndex++;}public void setAnimal(Animal animal) {this.animal = animal;this.message = "第"+stepCount+"步:农夫将" + (this.animal==null?" 自己 ":this.animal.type) + (this.direction ? "从左岸运到右岸" : "从右岸运到左岸");}}

Status.java

package com.sunrise.others;import java.util.ArrayList;
import java.util.List;/*** 当前状态* @author xuefeihu**/
public class Status {/** 左側 **/private List<Animal> left = new ArrayList<Animal>();/** 右側 **/private List<Animal> right = new ArrayList<Animal>();/** 人的位置 **/private boolean flag;/*** 构造状态对象--克隆对应数据* @param left 左側状态* @param right 右側状态* @param flag 人的位置* @param preSelf 前一个动作是否是人单独过河*/public Status(List<Animal> left, List<Animal> right, boolean flag) {this.left = newList(left);this.right = newList(right);this.flag = flag;}/*** 克隆List对象*/private List<Animal> newList(List<Animal> array){List<Animal> result = new ArrayList<Animal>();for(Animal animal : array){result.add(animal);}return result;}public List<Animal> getLeft() {return left;}public List<Animal> getRight() {return right;}public boolean getFlag() {return flag;}}

Animal.java

package com.sunrise.others;
/*** 动物实体* @author xuefeihu**/
public class Animal {public String type = null;public int id = -1;public int afraid = -1;public int control = -1;public Animal(String type, int id, int afraid, int control) {this.type = type;this.id = id;this.afraid = afraid;this.control = control;}/*** 设计一个制约关系:检查动物能否够并存* @param animal* @return*/boolean check(Animal animal){return this.afraid == animal.id || this.control == animal.id || animal.afraid == this.id || animal.control == this.id;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + id;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Animal other = (Animal) obj;if (id != other.id)return false;return true;}}

友情提示:(面向对象的思想大致觉得是正确的;因为时间仓促,如有改动代码,请您附上源代码与大家共享,谢谢!)

版权声明:本文博主原创文章。博客,未经同意不得转载。

养殖者运送猫狗过河问题(面向对象)相关推荐

  1. 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。编程解决猫狗鱼过河问题。

    import java.util.ArrayList; import java.util.List; import java.util.Random;/*** 一位老农带着猫.狗.鱼过河,河边有一条船 ...

  2. 面向对象_猫狗案例加入跳高功能代码实现

    /*猫狗案例,加入跳高的额外功能分析:从具体到抽象猫:姓名.年龄 吃饭.睡觉狗:姓名.年龄吃饭.睡觉由于有共性功能,所以,我们抽取一个父类:动物类:姓名.年龄吃饭();睡觉(){}猫:继承自动物类狗: ...

  3. 面向对象_猫狗案例加入跳高功能分析

    /*猫狗案例,加入跳高的额外功能分析:从具体到抽象猫:姓名.年龄 吃饭.睡觉狗:姓名.年龄吃饭.睡觉由于有共性功能,所以,我们抽取一个父类:动物类:姓名.年龄吃饭();睡觉(){}猫:继承自动物类狗: ...

  4. java多态猫狗吃骨头_javaSE学习(6):面向对象:多态的两个经典案例(猫狗案例和南北方人案例)...

    1.猫狗多态案例 /* 2019年5月19日9点48 @author 潇雷 猫狗案例多态版: */ class Animal{ public void eat(){ System.out.printl ...

  5. 面向对象_猫狗案例分析

    /*猫狗案例:先找到具体事物,然后发现具体事物有共性,才提取一个父类猫:成员变量:姓名,年龄,颜色构造方法:无参,带参成员方法:getXxx()/setXxx()eat()playGame()狗:成员 ...

  6. 面向对象之继承,抽象,接口的案例(刘意老师的猫狗案例)

    猫狗案例,加入跳高的额外功能 分析:从具体到抽象 猫: 姓名,年龄 吃饭睡觉 狗: 姓名,年龄 吃饭睡觉 由于有共性功能.所以我们抽取出一个父类: 动物: 姓名,年龄 吃饭(); 睡觉(){} 猫:继 ...

  7. PyTorch深度学习实战 | 猫狗分类

    本文内容使用TensorFlow和Keras建立一个猫狗图片分类器. 图1 猫狗图片 01.安装TensorFlow和Keras库 TensorFlow是一个采用数据流图(data flow grap ...

  8. Pytorch+CNN+猫狗分类实战

    文章目录 0.前言 1.猫狗分类数据集 1.1数据集下载(可选部分) 1.2数据集分析 2.猫狗分类数据集预处理 2.1训练集和测试集划分 2.2训练集和测试集读取 3.剩余代码 4.总结 0.前言 ...

  9. 朱俊彦团队最新论文:用GAN监督学习给左晃右晃的猫狗加表情,很丝滑很贴合...

    丰色 发自 凹非寺 量子位 报道 | 公众号 QbitAI GAN又被开发出一项"不正经"用途. 给猫狗加表情: 给马斯克加胡子: 不管视频中的脑袋怎么左晃右晃,这些表情都能始终如 ...

最新文章

  1. springboot拦截器@Autowired为null解决
  2. codeforces Palindromic characteristics(hash或者dp)
  3. java利用poi读取excel_java利用POI 读取EXCEL
  4. Python提取数字图片特征向量
  5. 剑英的区块链学习手记(二)
  6. [vue] 怎么缓存当前打开的路由组件,缓存后想更新当前组件怎么办呢?
  7. docker 安装部署nacos
  8. 你还在 Docker 中跑 MySQL?恭喜你,好下岗了!
  9. html设置桌面背景win7,怎么让电脑桌面背景动起来 win7设置动态背景桌面的方法...
  10. PPT投影仪演示设置
  11. 33个神经网络训练技巧
  12. 速抢:500份粉丝购书优惠券
  13. 基于 HTML5 WebGL 的 3D 水泥工厂生产线
  14. mipi屏参参数配置
  15. python将视频转为图片
  16. 数据结构课程设计之区块链工作原理模拟设计
  17. [嘿就这么样吧 谁看谁的脸色]井冈春天牌演.活力果子
  18. 浅析 Queue 和 Deque
  19. leetcode_399. 除法求值
  20. 计算机辅助地理教学的内容,计算机辅助地理教学的优效性的论文

热门文章

  1. iOS self 和 super 学习
  2. SpringBoot连接Redis超简单
  3. Web服务器超时处理
  4. 随笔② Java中的关键字 --- final关键字
  5. PHP常用的数组函数
  6. 编写Nginx启停服务脚本
  7. 开发人员必读的11本最具影响力书籍
  8. 个人博客作业第三周--必应词典分析
  9. mesos资源动态分配测试
  10. jQuery浏览器版本判断