约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
public class YuesefuTest {
public static void main(String[] args) {
int totalNum = 10;
int countNum = 3;
yuesefuByMyself(totalNum, countNum);
yuesefu(totalNum, countNum);
}
/**
* 此方法 k 为 list 的下标
* @param totalNum
* @param countNum
*/
public static void yuesefuByMyself( int totalNum,int countNum){
// 初始化人数
List<Integer> start = new ArrayList<Integer>();
for(int i=1; i<=totalNum; i++){
start.add(i);
}
// 此处的k为list的下标,开始报数人的下标,第一个人为0,第n个人为n-1
int k = 0;
while(start.size()>0){
// 下一个出列人的下标,因为是从当前报数人开始数,所以减1为下一个出列人的下标
k = k + countNum -1;
// 当 下标+1 超过了 list 的size
if(k + 1>start.size()){
// 当size 为 10 ,下标要取 10 ,最大下标为9,应该取 list 的 第一个,即下标为0,
// 同理,直接取余即可为正确下标
k = k % start.size();
}
System.out.print(start.get(k)+",");
// 出列,下一个开始报数人的下标即为出列人的下标
start.remove(k);
}
System.out.println();
}
public static void yuesefu(int totalNum,int countNum){
// 初始化人数
List<Integer> start = new ArrayList<Integer>();
for(int i=1; i<=totalNum; i++){
start.add(i);
}
// 从第K个开始计数
int k = 0;
while(start.size()>0){
k = k + countNum;
// 第m人的索引位置
k = k % (start.size()) -1;
// 判断是否到队尾
if(k<0){
System.out.print(start.get(start.size()-1)+",");
start.remove(start.size()-1);
k = 0;
} else {
System.out.print(start.get(k)+",");
start.remove(k);
}
}
System.out.println();
}
}