说过要将以前写过的文章转过来,这是以前的第一篇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, -1, 45);
}
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) + "号");
}
}
*描述约瑟夫游戏的类
*问题描述: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, -1, 45);
}
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) + "号");
}
}