約瑟夫算法(數學分析法)


//看了帖子後以爲有趣就實現了一把遞歸的約瑟夫算法算法

  

package test;

/**
 * 500個小孩圍成一圈,從第一個開始報數:1,2,3,1,2,3,1,2,3,……每次報3的小孩退出
	 問最後剩下的那個小孩,在之前500人裏是第幾個???
 */
public class Test {

	/**
	 * 約瑟夫標準循環非遞歸解法 
	 * @param n
	 * @param m
	 * @return
	 */
	public static int f2(int n, int m){
		
		int index = 0;
	    for (int i = 2; i <= n; i++) {
	        index = (index + m) % i;
	    }
		return index +1;
	}
	
	/**
	 * 約瑟夫遞歸算法
	 * @param n
	 * @param m
	 * @return 返回的結果+1 = 最終結果
	 */
	public static int f(int n,int m){
		
		int t = 0;
		if(n==1){
			return t;
		}else{
			t = ( f(n-1, m) + m)%n;
		}
		return t;
		
	}

	
	public static void main(String[] args) {
		//	
		int n = 500;
		int m = 3;
		
		//約瑟夫標準循環非遞歸解法 
		System.out.println(f2(n, m));//此方法來自帖子
		
		/*
		(函數)index表示(變量)n我的玩遊戲報(常量)m退出最後勝利者的編號.則有遞推公式:
		index(1) = 0;
		index(n) = (index(n-1) + m)%n;   (n>1)
		這個公式不是隻考慮一種場景得出的結果,而是抽象出廣泛的n得出的結論,
		
		*/
		/*
		 *f(1) = 0;//第0個
		 *f(2) = 1;//第1個
		 *f(3) = 1;//第2個
		 * */
		//參考上面的提示寫了下約瑟夫的遞歸算法
		System.out.println(f(n, m)+1);
		
		
	}
	
	
}

 

今天看到一個LinkedList版本的,測試了,結果同樣,補充上:函數

 

public static int removeNM(int n, int m) {   
        LinkedList ll = new LinkedList();   
        for (int i = 0; i < n; i++)   
            ll.add(new Integer(i + 1));   
        int removed = -1;   
        while (ll.size() > 1) {   
            removed = (removed + m) % ll.size();   
            System.out.println("出列:"+(ll.get(removed)));
            ll.remove(removed--);   
        }   
        return ((Integer) ll.get(0)).intValue();   
    }

 

 

 

 

 

 

打印結果:測試

436code

436遞歸

相關文章
相關標籤/搜索