1. 程式人生 > >約瑟夫環(報數遊戲)java實現

約瑟夫環(報數遊戲)java實現

開端

公司組織考試,一拿到考題,就是演算法裡說的約瑟夫環,仔細想想 以前老師將的都忘了,還是自己琢磨把~

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也是一個環的特性,頗為巧妙。還有一種就是以面向物件的思想,目前還