十五只猴子围成一圈选大王,依次1~7循环报数,报到7的猴子被淘汰,直到最后一只猴子称为大王,问,哪只猴子最后能称为大王?(约瑟夫环问题详解)

大家好,我是Ziph!

十五只猴子围成一圈选大王,依次1~7循环报数,报到7的猴子被淘汰,直到最后一只猴子称为大王,问,哪只猴子最后能称为大王?

用boolean数组解决方案(后面有用int数组解决的方案)

/** 
* @author Ziph
* @date 2020年2月23日
* @Email [email protected]
*/
public class ChooseKing {
	public static void main(String[] args) {
		//定义一个长度为15的数组,即:15只猴子
		boolean[] m = new boolean[15];
		//初始化数组为true以便后续淘汰为false的猴子
		for (int i = 0; i < m.length; i++) {
			m[i] = true;
		}
		System.out.println("恭喜第" + print(choiceKing(m)) + "只猴子被选为大王!");
	}
	
	//选一只猴子,即定了要淘汰14只猴子
	public static boolean[] choiceKing(boolean[] m) {
		int monkeys;//记录为true的猴子数量
		int count = 0;//记录报的数字
		do {
			monkeys = 0;//每次初始化猴子数量
			for (int i = 0; i < m.length; i++) {
				if (m[i] == false) {//false为被淘汰的猴子
					continue;
				}
				count++;//猴子报的数字
				if (count % 7 == 0) {//报数为7,也就是能被7整除的数
					m[i] = false;//淘汰此猴子,把true改为false
				}
				if (m[i] == true) {//随着猴子的淘汰,为true的猴子越来越少
					monkeys++;	   //直至为true的猴子为1为止
				}
			}
		} while (monkeys != 1);//淘汰至剩一个猴子(唯一一只true)结束
		return m;
	}
	
	//打印获取猴王位置
	public static int print(boolean[] m) {
		int j = 0;
		//遍历数组中的猴子选出那唯一一只为true的猴子并打印是第几只
		for (; j < m.length; j++) {
			if (m[j] == true) {
				j++;//在for循环j猴子下标的基础上加1即是数组中第几只猴子是猴王
				break;//找到猴王,结束循环
			}
		}
		return j; 
	}
}

用int数组解决方案一
这一个方法比数组方案二简单,数组方案二还涉及到数组的元素的删除和赋值新数组地址而最后剩一个int[0]即是猴王,并打印!

/** 
* @author Ziph
* @date 2020年2月23日
* @Email [email protected]
*/
public class Monkey {
	public static void main(String[] args) {
		//新建15只猴子
		int[] a = new int[15];
		//给猴子赋值编号1~15
		for (int i = 0; i < a.length; i++) {
			a[i] = i + 1;
		}
		//定义计数器
		int b = 0;//计报数
		int c = 0;//计淘汰的猴子数
		for (int i = 0; i < a.length; i++) {
			if (a[i] != 0) {//寻找没有被淘汰的猴子
				b++;//报数
				if (b % 7 == 0) {//寻找报数为7的猴子
					a[i] = 0;//将报数为7的猴子赋值为0,以便后续淘汰
					c++;//统计被淘汰的猴子数
				}
			}
			if (c == 14) {
				break;//剩下最后一只猴子也就是猴王
			}
			if (i == 14) {//循环遍历所有猴子,以便挑选报数为7的猴子
				i = -1;
			}
		}
		for (int j : a) {//增强for循环遍历猴子们
			System.out.print(j + " ");
		}
		System.out.println();
		for (int i = 0; i < a.length; i++) {
			if (a[i] != 0) {
				System.out.println("恭喜第" + (i + 1) + "只猴子被选中为猴王!");
				break;
			}
		}
	}
}

用int数组解决方案二

/** 
* @author Ziph
* @date 2020年2月23日
* @Email [email protected]
*/
public class MonkeyKing {
    public static void main(String[] args){
        int[] a = new int[15];
        //为数组赋值1~15猴子编号
        for (int i = 0; i < a.length; i++) {
			a[i] = i;
		}
        //新建b数组,接受调用choice方法后的a数组
        int[] b = new int[1];
        b = choice(a);
        System.out.println("恭喜第" + b[0] + "只猴子被选中为大王!");
    }
    
    public static int[] choice(int[] a) {
    	int count = 0;//报的数字首次初始化
    	while (a.length != 1) {//最后剩1只猴子,长度为1
    		int sign = 0;//初始化报数7猴子的个数
    		for (int i = 0; i < a.length; i++) {
				count++;//开始报数
				if (count == 7) {
					a[i] = 0;
					count = 0;//重新报数,初始化为0
					sign++;//报数为7猴子的个数
				}
			}
    		//将报数为7的猴子淘汰掉,也就是从数组中删除,数组长度-1
    		//sign记录了一次while循环也就是遍历一次数组淘汰猴子的个数
    		//数组长度减去淘汰猴子的个数长度为新数组的长度
    		int[] newA = new int[a.length - sign];
    		int index = 0;//记录没有淘汰猴子的个数做下标
    		for (int i = 0; i < a.length; i++) {
				if (a[i] != 0) {//没有被淘汰的猴子
					newA[index++] = a[i];//把没有被淘汰的猴子赋给新数组
				}
			}
    		a = newA;
    	}
    	return a;
    }
}

执行效果:

在这里插入图片描述

发布了62 篇原创文章 · 获赞 113 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44170221/article/details/104466028