马士兵 Java 第5章(1) 分别使用面向对象和面向结构(数组)的设计方法来实现“数三退一”

说明:本文转载自  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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值