說明:本文轉載自 http://blog.csdn.net/yyg_juke/article/details/2233397
問題如下:
有500個小孩圍成一圈,從第一個小孩開始數數,1 2 3.。。。。。當數到第三個人時,退出圈子,第四個人再從1開始數,問最後還剩下哪個人。
// 1.通過物件導向來實現數3退1// 實現的是具有迴環的雙向鏈表//說明:以5個小孩為例,在while處設定斷點,進行debug,觀察countNum、當前小孩k(id號) 、當前小孩圈(first和last的id號)的變化情況,會對程式的執行過程有更清醒的認識。public class Count3Quit2 { public static void main(String[] args) {//建立一個有500個小孩的圈 KidCircle kc = new KidCircle(500);// k用來記錄當前指向的那個小孩,剛開始時設定圈首的小孩為k Kid k = kc.first;// countNume用來記錄小孩數的數(1、2、3) int countNum = 0;// while成立則說明圈內還不止一個小孩,需要繼續往下數數 while(kc.count > 1) { countNum++; if(countNum == 3) {// 當前小孩數的數是3 的話,將數數標誌清0,該小孩退出 countNum = 0; kc.delete(k); }// 移動k標誌到下一個小孩頭上 k = k.right; }// while不成立的時候,說明此時該圈中就剩下一個小孩了,將其id號輸出即可 System.out.println("最後一個小孩的編號是:" + kc.first.id); }}class Kid {// 小孩編號 int id;// 小孩的左手邊也是一個小孩 Kid left;// 小孩的右手邊也是一個小孩 Kid right;}class KidCircle {// count用來記錄圈中小孩數 int count = 0;// first用來記錄當前圈的第一個小孩 Kid first;// last用來記錄當前圈的最後一個小孩 Kid last; // 小孩圈的構造方法,可以建立n個小孩的圈 KidCircle(int n) { for(int i = 0; i < n; i++) { add(); } } // 往圈中增加小孩 public void add() { Kid k = new Kid();// 當前建立的小孩的編號就是小孩圈的記錄號 k.id = this.count; if(count <= 0) {// 此時還沒有小孩// 小孩圈的第一個和最後一個小孩都是k// 小孩k的左手邊和右手邊的小孩都是他自己 this.first = k; this.last = k; k.left = k; k.right = k; } else {// 把這個小孩k插入到圈的末尾// 當前圈的第一個小孩的左手牽了k this.first.left = k;// 當前圈的最後一個小孩的右手牽了k this.last.right = k;// k的左手牽的是當前圈的最後一個小孩 k.left = this.last;// k的右手牽的是當前圈的第一個小孩 k.right = this.first;// k變成了圈的最後一個小孩 this.last = k; }// 當前圈的小孩數增1 this.count++; } // 把圈中的k小孩刪掉 public void delete(Kid k) { if(this.count == 0) {// 已經沒有小孩了 System.out.println("There is no kid!"); } else if(this.count == 1) {// 就最後一個小孩了,將圈的首尾設定為null,圈就不存在了 this.first = this.last = null; } else {// k左邊小孩的右手牽了k右邊的小孩 k.left.right = k.right;// k右邊小孩的左手牽了k左邊的小孩 k.right.left = k.left; // 假如刪除的k是圈的第一個小孩 if(k == this.first) {// k的右邊的小孩就變成了第一個小孩 this.first = k.right;// 假如刪除的k是圈的最後一個小孩 } else if(k == this.last) {// k的左邊的小孩就變成了最後一個小孩 this.last = k.left; }// 圈中小孩數目減1 this.count--; } }}
測試結果:
最後一個小孩的編號是:435
// 2.使用數組來實現數3退1
//說明:以10個小孩為例,在while處設定斷點,進行debug,觀察leftCount 、countNum 、index 和一維數組bArray中各布爾值的變化情況,會對程式的執行過程有更清醒的認識。
public class Count3Quit { public static void main(String[] args) { // 通過標誌true或false來實現判斷該小孩是否還在圈中 boolean[] bArray = new boolean[500]; for(int i = 0; i < bArray.length; i++) { bArray[i] = true; } int leftCount = bArray.length; int countNum = 0; int index = 0; while(leftCount > 1) { if(bArray[index] == true) { countNum++; if(countNum == 3) { countNum = 0; bArray[index] = false; leftCount--; } } index++;// 數到圈的末尾了,要將編號index清0,再重新數 if(index == bArray.length) { index = 0; } } for(int i = 0; i < bArray.length; i++) { if(bArray[i] == true) { System.out.println("最後一個小孩的編號是:" + i); } } }}
測試結果:
最後一個小孩的編號是:435