算法:算法概述之约瑟夫算法
约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
public class YuesefuTest {
public static void main(String[] args) {
int totalNum = 10;
int countNum = 3;
int startNum = 8;
yuesefuByMyself(totalNum, countNum,startNum);
yuesefu(totalNum, countNum,startNum);
}
/**
* 此方法 k 为 list 的下标
* @param totalNum
* @param countNum
*/
public static void yuesefuByMyself( int totalNum,int countNum,int startNum){
//初始化人数
List<Integer> start = new ArrayList<Integer>();
for(int i=1; i<=totalNum; i++){
start.add(i);
}
//此处的k为list的下标,开始报数人的下标,第一个人为0,第n个人为n-1
int k = startNum;
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,int startNum){
//初始化人数
List<Integer> start = new ArrayList<Integer>();
for(int i=1; i<=totalNum; i++){
start.add(i);
}
//从第K个开始计数
int k = startNum;
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();
}
}
输出结果为:
1,4,7,10,5,9,6,3,8,2,
1,4,7,10,5,9,6,3,8,2,