約瑟夫算法的介紹:
約瑟夫環:已知n我的(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數,
數到m的那我的出列;他的下一我的又從1開始報數,數到m的那我的又出列;依此規律重複下去,
直到圓桌周圍的人所有出列java
如下爲log信息,幫助理解實現思路算法
全部的數據爲: 1 2 3 4 5 6 7 8 9 10 第1次循環,數據爲: 1 2 3 4 5 6 7 8 9 10 -----------被刪除的數據爲:6 第2次循環,數據爲: 7 8 9 10 1 2 3 4 5 -----------被刪除的數據爲:2 第3次循環,數據爲: 3 4 5 7 8 9 10 1 -----------被刪除的數據爲:9 第4次循環,數據爲: 10 1 3 4 5 7 8 -----------被刪除的數據爲:7 第5次循環,數據爲: 8 10 1 3 4 5 -----------被刪除的數據爲:5 第6次循環,數據爲: 8 10 1 3 4 -----------被刪除的數據爲:8 第7次循環,數據爲: 10 1 3 4 -----------被刪除的數據爲:1 第8次循環,數據爲: 3 4 10 -----------被刪除的數據爲:10 第9次循環,數據爲: 3 4 -----------被刪除的數據爲:4 總數:[10] 須要刪除掉的數據的位置:[6] 最後一個被刪除掉的數據[3]
主要的實現思想:oop
2.一、兩個list:一個裝以前已經讀過的數據,一個裝尚未讀過的數據code
2.二、從沒有讀過的數據裏面刪除應該刪除的數據。rem
每次到應該刪除的數據之後,將已經讀過的數據放到沒有讀過的後面,以後再將已經讀過的數據清空掉get
若是沒有讀過的數據,已經爲空了,那麼則須要將已經讀過的數據再加進去,並將已經讀過的數據清空class
2.三、判斷,若是已經讀過的數據list長度爲1,未讀數據爲空,則結束循環test
/** * 約瑟夫算法的實現 * 約瑟夫算法的介紹: * 約瑟夫環:已知n我的(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數, * 數到m的那我的出列;他的下一我的又從1開始報數,數到m的那我的又出列;依此規律重複下去, * 直到圓桌周圍的人所有出列 */ public class YuesefuTest { public static void main(String[] args) { int total = 5; int removeAt = 3; // patternTwo(total, removeAt); // patternTwo(10, removeAt); patternTwo(10, 6); // testOne(); } private static void testOne(){ ArrayList<Integer> unReadList = new ArrayList<Integer>();//沒有讀過的list ArrayList<Integer> readedList = new ArrayList<Integer>();//已經讀過的list for(int i = 0;i< 5;i++){ unReadList.add(i); } for(int i = 5;i<10;i++){ readedList.add(i); } readedList.addAll(readedList.size(),unReadList); unReadList.clear(); System.out.println("全部的數據:"); for(int i = 0;i<readedList.size();i++){ System.out.println(" "+readedList.get(i)); } System.out.println(); System.out.println("剩下的數據:"); for(int i = 0;i<unReadList.size();i++){ System.out.println(" "+unReadList.get(i)); } } /** * 第二種方法 * @param total * @param removeAt */ private static void patternTwo(int total, int removeAt) { //兩個list:一個裝以前已經讀過的數據,一個裝尚未讀過的數據 ArrayList<Integer> unReadList = new ArrayList<Integer>();//沒有讀過的list ArrayList<Integer> readedList = new ArrayList<Integer>();//已經讀過的list for(int i = 1;i<=total;i++){ unReadList.add(i); } System.out.println("全部的數據爲:"); printAllNum(unReadList); int loopCount = 1; while(true){ System.out.println("第"+loopCount+"次循環,數據爲:"); printAllNum(unReadList); for(int i = 1;i< removeAt;i++){ if(unReadList.size() == 0){//若是沒有讀過的數據,已經爲空了,那麼則須要將已經讀過的數據再加進去,並將已經讀過的數據清空 unReadList.addAll(unReadList.size(),readedList); readedList.clear(); } int value = unReadList.remove(0); readedList.add(value); } if(unReadList.size() == 0){ unReadList.addAll(unReadList.size(),readedList); readedList.clear(); } int i = unReadList.remove(0);//從沒有讀過的數據裏面刪除應該刪除的數據。 System.out.print(" -----------被刪除的數據爲:"+i+"\n"); //每次到應該刪除的數據之後,將已經讀過的數據放到沒有讀過的後面,以後再將已經讀過的數據清空掉 unReadList.addAll(unReadList.size(),readedList); readedList.clear(); loopCount++; if(unReadList.size() == 1 && readedList.size() == 0){//判斷,若是已經讀過的數據list長度爲1,未讀數據爲空,則結束循環 break; } } System.out.println("總數:["+total+"] 須要刪除掉的數據的位置:["+removeAt+"] 最後一個被刪除掉的數據["+unReadList.get(0)+"]"); } private static void printAllNum(ArrayList<Integer> allNum){ if(null != allNum && allNum.size() > 0) { System.out.println(); for (int i =0;i<allNum.size();i++) { System.out.print(" "+allNum.get(i)); } System.out.println(); } } }