約瑟夫環(隊列解法)
隊列操作:
每個人都報數一次:可以創建一個計數器,每當報數時計數器+1,(報到9的人就扔進大海),代表:計數器 % 9 ==
0,
/**
* 約瑟夫環:15個基督教徒和15個非教徒在海上遇險,必須將其中一半的人投入海中,其餘的人才能倖免於難,
* 於是30個人圍成一圈,從某一個人開始從1報數,報到9的人就扔進大海,他後面的人繼續從1開始報數,重複上面的規則,直到剩下15個人爲止。
* 結果由於上帝的保佑,15個基督教徒最後都倖免於難,問原來這些人是怎麼排列的,哪些位置是基督教徒,哪些位置是非教徒。
* @author zengxin
*
*/
public class Pahe11約瑟夫環 {
@Test
public void ListTest() {
Queue<Integer> queue = new LinkedList<>();
int personNum = 30; //總人數
int liveNum = 15;//基督人數
int key = 9;//數的關鍵字
//初始化人蔘數
for(int i = 1;i<=personNum;i++){
queue.add(i);
}
List<Integer> flaseList = getFlase(queue, personNum, key, liveNum);
System.out.println();
Queue<Integer> trueQueue = getTrue(queue, flaseList);
//遍歷出 基督成員
for(Integer i : trueQueue){
System.out.print("基:"+i+" ");
}
}
//獲取非基督人員
private static List<Integer> getFlase(Queue<Integer> queue,int personNum,int key,int liveNum){
List<Integer> flaseList = new ArrayList<>();//非基督徒人員
int count =0;
while(queue.size()>liveNum){
//出隊操作
int k = queue.poll();
//計數器
count++;
if(count % key == 0){
System.out.print("非:"+k+" ");
flaseList.add(k);
}else{
//當不滿足時,繼續入棧
queue.add(k);
}
}
return flaseList;
}
//移除非基督成員
private Queue<Integer> getTrue(Queue<Integer> queue,List<Integer> flaseList){
for(Integer i : flaseList){
queue.remove(i);
}
return queue;
}