先参考一下百度百科约瑟夫环概念
1.一群人围在一起坐成环状(如:N) 2.从某个编号开始报数(如:K) 3.数到某个数(如:M)的时候,此人出列,下一个人重新报数 4.一直循环,直到所有人出列,约瑟夫环结束。
/**
* @param totalNum 总共数的个数
* @param cycleNum 报数的大小
* @param startNO 开始报数的编号
*/
public static void ysf(int totalNum, int cycleNum,int startNO) {
// 初始化人数
List<Integer> start = new ArrayList<Integer>();
for (int i = 1; i <= totalNum; i++) {
start.add(i);
}
// 从下标为K开始计数
int k = startNO-1;
while (start.size() >0) {
System.out.println(start);
// 第m人的索引位置
// k+cycleNum-1 这个减一是因为自己也会喊,即这一轮的开始角标也要占周期的一个
k = (k + cycleNum-1) % (start.size());
System.out.println(start.get(k));
start.remove(k);
}
}
方法二
/**
* @param totalNum 总共数的个数
* @param cycleNum 报数的大小
* @param startNO 开始报数的编号
*/
private static void method2(int totalNum, int cycleNum,int startNO){
boolean[] arr = new boolean[totalNum];
for (int i = 0; i < arr.length; i++) {
arr[i] = true; //下标为TRUE时说明还在圈里
}
int curLength = totalNum;
int count = 0; // 报数计数
int index = startNO-1; // 初始位置的角标
while (curLength > 1){
if (arr[index]){
count++; // 报了一次数
if (count == cycleNum){
arr[index] = false; // 表示退出圈子
curLength--; // 去掉一个当前数量就减一
count = 0; // 找到一个,清0
}
}
index++;
if (index == totalNum) // 到了totalNum-1 为最后一个,到了总数说明该下一圈的第一个
index = 0;
}
for (int i = 0; i < totalNum; i++) {
if (arr[i])
System.out.println(i+1); // 角标加1 是第几个
}
}