package yuesefu;
* 约瑟夫问题解法
* 使用递归算法
* 2018年5月19日 冯超华
*
* 结果:如果mensCNT=41,则结果=15,30(基于从0开始,如果是从1算起,则为16,31)
*/
public class Yuesefu {
java.util.List<Integer> mens = new java.util.ArrayList<Integer>(); //人员列表,为适应java习惯,用0~40来表示这41个人
private static final Integer mensCNT = 41; //人数,可以尝试修改为其他数字
/**
* 构造函数,将mens填充,用0-40来代表这41个人,或者其他数量的人
*/
public Yuesefu() {
//人的编号为0-40
for(Integer i = 0; i < mensCNT; i ++) {
mens.add(i);
}
}
private int now = 1; //当前数的数,从1 i开始,数到3的人自杀
private int position = 0; //当前数数那个人的位置,用来标记让哪个位置的人自杀
/**
* 递归执行,计算下一个该自杀的人并从list里删除他
*/
public void killNext() {
if(mens.size() <= 2) { //如果只剩不超过2个人了,则停止(实际上就是剩下2人的时候停止)//如果没有这一段,会死循环
System.out.println("幸存者(从0开始):" + mens.toString() + ",若是从1开始的话,每个数字加1");
return;
}
if(position >= mens.size()) { //如果当钱数数那个人超过了队伍里的最后一个,从回到队伍的开头,实际上就是让这个队伍排成圆圈
position = 0;
}
System.out.println("当前position:" + position + ",当前幸存者:" + mens.toString() + ",剩余人数:" + mens.size());
if(now < 3) { //数数时如果不是3的,就跳过
position ++; //位置后移
now ++; //数字下一个
}else {
System.out.println("自杀:" + mens.remove(position)); //如果数到3,则自杀----在这里就是从list里移除它//remove(Integer)操作会返回被移除的那个对象,所以这里不需要用get(Integer)
//position --; //这里不需要--,虽然少了一个人,但是下一个人补上来了,这个人会数1,但是他的位置position就是刚刚自杀掉的那个倒霉蛋的位置
now = 1; //数数重新开始
}
killNext();
}
public static void main(String[] args) {
new Yuesefu().killNext();
}
}