約瑟夫環(報數遊戲)java實現
阿新 • • 發佈:2019-05-24
開端
公司組織考試,一拿到考題,就是演算法裡說的約瑟夫環,仔細想想 以前老師將的都忘了,還是自己琢磨把~
package basic.gzy; import java.util.Iterator; import java.util.LinkedList; import java.util.Queue; /** * 約瑟夫環 報數遊戲 比如 5,3 則最後一個退出遊戲的是4號 * 五個人圍城環,數到三退出遊戲,然後往下輪,最後一個為倖存者 * 要滿足報數小於人數 * @author mac * */ public class BSYX { public static void main(String[] args) { // System.out.println("---生存者"+baoshu1(5,3)); // System.out.println("---生存者"+baoshu1(12,3)); System.out.println("---生存者"+baoshu2(5,3)); } public static int baoshu1(int num, int count) { // 最後退出的是第n個人 int n = 0; // 剩餘的人 int rest = num; // 利用陣列初始化為0作為標識位 int[] arr = new int[num + 1]; // 初始化次數 int index = 1; for (int i = 1, j = 1; i < num + 1; i++, j++) { //跳過已退出的資料 while (arr[i] == 1) { if(i<num) { i++; }else { i=1; } } if (rest == 1) { n = i; break; } if (j == 1) { System.out.println(); System.out.print("第" + index + "次遊戲," + i + "[" + j + "],"); } else if (j < count ) { System.out.print(i + "[" + j + "],"); } else { System.out.print(i + "[" + j + "]--" + i + "退出遊戲"); // 重置j會++故設為0,遊戲次數+1,陣列做標記位已退出,剩餘人少1 j = 0; index++; rest--; arr[i] = 1; } if (i == num ) { // 回到頭,會++故設為0 i = 0; } } return n; } /** * 利用佇列 * @param num * @param count * @return */ public static int baoshu2(int num, int count) { int n = 0; int rest = num; int index = 1; int l = 0; Queue<Integer> list = new LinkedList<Integer>(); for(int i=1;i<num+1;i++) { list.add(i); } while(!list.isEmpty()) { Integer poll = list.poll(); l++; if(rest == 1) { n=poll; break; } // 靈活運用求餘 if(l%count == 1) { System.out.println(); list.add(poll); System.out.print("第" + index + "次遊戲," + poll + "[" + 1 + "],"); }else if(l%count==0) { System.out.println(poll + "[" + count + "]--" + poll + "退出遊戲"); rest --; index++; }else { list.add(poll); System.out.print(poll + "[" + poll%count + "],"); } } return n; } }
總結:第一種是自己想的lowlow的寫法,程式碼冗餘,可讀性一般。第二種利用了佇列雙向連結串列LinkedList也是一個環的特性,頗為巧妙。還有一種就是以面向物件的思想,目前還