導入Java . util . ArrayList;
導入Java . util . list;
導入JUnit . framework . test case;
/**
*約瑟夫斯環
*已知n個人(用數字1,2,3表示...n)正圍坐在圓桌旁。從編號為k的人開始報數,數到m的人就步出;他的下壹個人從1開始報數,數到m的人又出隊了;重復這個規則,直到圓桌周圍的人都不在壹條線上。
*
* @作者陳辰
*/
公共類約瑟夫斯擴展測試用例{
公共無效測試(){
findMonkey(50000,3);
myJosephus(50000,3,1);
}
/**
*用純數學方法解決問題,原算法不提供參數啟動。
*長度=30000000,運算時間將超過1s。
*長度=200000,操作時間將超過1 ms。
*步長值對操作時間幾乎沒有影響。
* O(1)
* @param length初始化隊列的長度。
* @param步驟m
* @param start k
* @返回
*/
受保護的void findMonkey(int length,int step) {
int start = 0;
long start time = system . current time millis();
for(int I = 2;我& lt=長度;i++){
start =(start+step)% I;
}
long stop time = system . current time millis();
System.out.println("約瑟夫斯花費時間:"+(stop time-start time)+" ms ");
system . out . println(start+1);
}
/**
*自完成法:java可以模擬實際情況解決問題。
*步長越小,花費的時間越長。
*長度=40000,運算時間將超過1s。
*長度=5000,操作時間將超過1 ms。
* O(納米)
* @param長度
* @param步長
* @param start
*/
受保護的void myJosephus(int length,int step,int start) {
//存儲人們的隊列
列表& lt字符串& gtlist = new ArrayList & lt字符串& gt();
for(int I = 1;我& lt=長度;i++) {
list . add((Integer)I)。toString());
}
//開始報數的人所在隊列的行數。初始化電流= start-1,電流為下標。
int電流= start-1;
long start time = system . current time millis();
做{
//從自己算,所以-1。
當前+=步驟-1;
//當當前超過整個隊列的實際長度時,需要回到頭部繼續計數。
while(當前& gt= list.size()) {
current-= list . size();
}
//數到M的人走出隊列。
list.remove(當前);
//壹直數,直到剩下最後壹個人。
} while(列表!= null & amp& amplist . size()& gt;1);
long stop time = system . current time millis();
System.out.println("約瑟夫斯花費時間:"+(stop time-start time)+" ms ");
system . out . println(list . iterator()。next());
}
}