三个怪兽和三个和尚过河java版
简介
继之前 三个桶分八升水java版 后,《算法的乐趣》第六章-妖怪和和尚过河问题,和之前第五章的算法大同小异,巩固下对于树的深度遍历,以及在遍历的时候对于栈的使用,下面付上java版代码。
代码
App.java
主类,包含了所有算法和流程
package com.yixin.arithmetic.three;
import com.yixin.arithmetic.three.enums.ActionEnum;
import com.yixin.arithmetic.three.enums.BoatDirectionEnum;
import com.yixin.arithmetic.three.model.ItemState;
import java.util.Iterator;
import java.util.Stack;
/**
* 有三个和尚和三个妖怪要利用一个小船过河
* 一个船同时最多只能做两个人,同时,无论在两岸还是再船上
* 当妖怪的数量大于和尚的数量时,和尚就会被吃掉
* 现在需要安排一种过河的方式,保证和尚和妖怪都能顺利过河,并且和尚不会被吃掉。
*/
public class App {
static int index = 0;
private static Stack<ItemState> itemStateStack = new Stack<ItemState>();
public static void main( String[] args ) {
ItemState itemState = new ItemState();
itemState.setLocalMonk(3);
itemState.setLocalMonster(3);
itemState.setBoatDirection(BoatDirectionEnum.LOCAL_2_REMOTE);
itemStateStack.add(itemState);
search();
}
/**
* 核心方法,查询,遍历树
*/
public static void search(){
ItemState itemState = itemStateStack.peek();
ActionEnum[] actionEnumAry = ActionEnum.values();
logIfEnd(itemState);
for(ActionEnum actionEnum : actionEnumAry){
if(!canAcross(itemState , actionEnum)){
continue;
}
ItemState nextItemState = across(itemState , actionEnum);
if (isAlreadyProcess(nextItemState)) {
continue;
}
//利用栈的数据结构,遍历树形结构
itemStateStack.add(nextItemState);
search();
itemStateStack.pop();
}
}
/**
* 查询当前状态是否可以过河
* @param itemState 当前状态
* @param actionEnum 当前尝试的动作
* @return 是否可以
*/
private static boolean canAcross(ItemState itemState , ActionEnum actionEnum){
//移动后在local的和尚数量小于怪兽数量不行
//移动后在remote的和尚数量小于怪兽数量不行
//移动后local或remote的和尚和怪兽数量小于0不行
if(itemState.getBoatDirection() == actionEnum.nextBoatDirection){
return false;
}
if(itemState.getLocalMonk() + actionEnum.monkCount < 0
|| itemState.getLocalMonster() + actionEnum.monsterCount &