数组实现的约瑟夫问题(Java)

  说过要将以前写过的文章转过来,这是以前的第一篇blog。

  之前是用C++写的,现在做Java了,索性改成了Java版的。看了看以前C++的实现,哈哈,实现得挺烂的,不贴也罢。Java代码如下:

 

/***************************************************************************************
 *描述约瑟夫游戏的类
 *问题描述:totalNum个人围成圆圈就座,从某人开始编号,从编号为startNum开始从1报数,报数为
 * perNum的人退出圆圈。然后由下一个人从1重新报数,如此循环。
 *created by: jdk1.5.0_07 + Notepad++ 
 * Copyright (C) CManLH 2007.1.9
 ****************************************************************************************
*/

public   class  Josephus  {
    
private int startNum;        //第一个开始报数的参与者的编号
    private int totalNum;        //参与游戏的总人数
    private int perNum;            //报到此数字则出局
    private int man[];            //按座位编号排列
    private int out[];            //按出局次序排列
    
    
//构造函数,如果参数出错就抛出异常
    Josephus(int startNum, int perNum, int totalNum) throws Exception {
        
if ( totalNum < 0 || startNum < 0 || startNum > totalNum || perNum < 0 ) {
            
throw new Exception("Josephus构造函数参数错误");
        }

        
        
this.startNum = startNum;
        
this.perNum = perNum;
        
this.totalNum = totalNum;
        
        calculate();
    }

    
    
//游戏模拟函数
    private void calculate() {
        
int count = 1;
        
int perCounter = 0;
        man 
= new int[totalNum];
        out 
= new int[totalNum];
        
        
for ( int i = startNum-2; count <= totalNum; count++ ) {
            
do {
                i 
= (i+1)%totalNum;                //做循环处理
                if ( man[i] == 0 ) {
                    perCounter
++;
                }

                
if ( perCounter == perNum ) {     //当报数刚好为出局的数字时
                    perCounter = 0;
                    
break;
                }

            }
 while ( true );
            man[i] 
= count;
        }

        
        
for ( int j = 0; j < totalNum; j++ ) {
            out[man[j]
-1= j+1;
        }

    }

    
    
//获得在num编号座位上的游戏者出局的次序号
    public int positionNumToKilledNum(int num) {
        
return (num > 0 && num <= totalNum) ? man[num-1] : -1;
    }

    
    
//获得在第num出局游戏者的座位号
    public int killedNumToPositionNum(int num) {
        
return (num > 0 && num <= totalNum) ? out[num-1] : -1;
    }

    
    
public String toString() {
        StringBuilder string 
= new StringBuilder(100);
        string.append(
"此约瑟夫游戏信息如下: "
            
+ "参与人数:" + totalNum + " 开始报数人的编号:" + startNum + " 每次出局所报数:" + perNum +" "
            
+ "参加者在环中的编号(出局的次序): ");
            
        
for ( int i = 0 ; i < totalNum; i++ ) {
            string.append((i
+1+ "(" + man[i] + ")  ");
        }

        
        string.append(
" 参加者出局的次序(在环中的编号): ");
        
for ( int j = 0; j < totalNum; j++ ) {
            string.append((j
+1+ "(" + out[j] + ")  ");
        }

        
        
return new String(string);
    }

    
    
//测试
    public static void main(String[] args) {
        Josephus josephus 
= null;
        
try {
            josephus 
= new Josephus(3-145);
        }

        
catch ( Exception e ) {
            System.out.println(e);
            
return;
        }

        
        System.out.println(josephus);
        System.out.println(
"排第25号的人是第" + josephus.positionNumToKilledNum(25+ "个出局");
        System.out.println(
"第25个出局的人是排在第" + josephus.killedNumToPositionNum(25+ "");
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值