约瑟夫环

用数组实现约瑟夫出圈问题,n个人排成一圈,从第一个开始报数,报到m的人出圈,
剩下的人继续开始从1报数,直到所有的人都出圈为止。对于给定的n,m,
求出所有的人出圈顺序。

 

转的一个比较易懂地方法

 

  1. package class_only;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /** */
  5. /**
  6.  * @author huangjie
  7.  * @createDate 2008-11-20
  8.  * @package
  9.  * @fileName OutofCircle.java
  10.  **/
  11. public class Test {
  12.     public static void main(String[] args) {
  13.         OutOfCirle ooc = new OutOfCirle(10100);
  14.         ooc.begin();
  15.     }
  16. }
  17. class OutOfCirle {
  18.     // 报出了这个数的都退出
  19.     public static int outNumber;
  20.     // 总的有多少个人
  21.     public static int manSize;
  22.     // 上面2个一开始就固定好了,所以我就声明成static
  23.     // 圈中的人
  24.     private List<Man> allMan;
  25.     // 现在已经报到第几号了,初始化为1
  26.     private int nowNumber = 1;
  27.     // 现在已经报到第几个人了,初始化为0;
  28.     private int nowMan = 0;
  29.     public OutOfCirle(int manSize, int outNumber) {
  30.         OutOfCirle.manSize = manSize;
  31.         OutOfCirle.outNumber = outNumber;
  32.         init();
  33.     }
  34.     private void init() {
  35.         allMan = new ArrayList();
  36.         // 初始化所有人,即把所有人编上号
  37.         int manNumber = 0;
  38.         while (OutOfCirle.manSize != manNumber) {
  39.             allMan.add(new Man(++manNumber));
  40.         }
  41.     }
  42.     public void begin() {
  43.         while (allMan.size() > 0) {
  44.             Man man = this.select();
  45.             // 把这个人T出去
  46.             allMan.remove(man);
  47.             // 当T的是最后一个的时候,又从第一个开始数
  48.             if (nowMan == allMan.size()) {
  49.                 nowMan = 0;
  50.             }
  51.             // 说明T的不是最后一个
  52.             // T的人的后面的都会往前移一个位置
  53.             // 这样就把原来的nowman代替了,就可以从nowman开始数了
  54.             else {
  55.             }
  56.             // 选出来了以后又从1开始报
  57.             nowNumber = 1;
  58.             System.out.println("我是第" + man.getNumber() + "号,我现在被T出去了,我是第"
  59.                     + (manSize - allMan.size()) + "个被T的" + ",还有"
  60.                     + allMan.size() + "在圈里");
  61.         }
  62.         System.out.println("所有人都被T出去完了");
  63.     }
  64.     // 找出报outNumber的人
  65.     private Man select() {
  66.         Man man = null;
  67.         // 没选出来就一直报数
  68.         while (man == null) {
  69.             // nowman报数
  70.             Man m = allMan.get(nowMan);
  71.             boolean right = m.reckon(nowNumber);
  72.             // 就是他了
  73.             if (right) {
  74.                 man = m;
  75.             }
  76.             // 说明不是他
  77.             else {
  78.                 // 报的数字到下一个
  79.                 nowNumber++;
  80.                 // 人也到下一个去
  81.                 nowMan++;
  82.                 // 说明已经到了最后一个了
  83.                 if (nowMan == allMan.size()) {
  84.                     // 又从第一个开始报数
  85.                     nowMan = 0;
  86.                 }
  87.             }
  88.         }
  89.         return man;
  90.     }
  91. }
  92. class Man {
  93.     private int number;
  94.     public Man(int number) {
  95.         this.number = number;
  96.     }
  97.     public int getNumber() {
  98.         return number;
  99.     }
  100.     // 报数:判断报出的数字是否和outNumber
  101.     public boolean reckon(int num) {
  102.         return num == OutOfCirle.outNumber;
  103.     }
  104. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值