约瑟夫环 --- 面向对象 --- java代码

约瑟夫环 的 面向对象
解法

罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

如有疑问请参考:http://blog.fishc.com/1959.html

实现代码如下:

程序的入口

/Josephus/src/com/kodoyang/Josephus/Demo.java


package com.kodoyang.Josephus;

/**
* ---------------------------------------------------------------------
*
* 在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,
* 39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,
* 41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,
* 然后再由下一个重新报数,直到所有人都自杀身亡为止。
* 然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,
* 他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
* ----------------------------------------------------------------------
*
* 网站上有很多实现了,我提供一种面向对象的实现
* 把约瑟夫环看成一个正多边形,每个人占据顶点的位置
* ----------------------------------------------------------------------
*
* 程序的入口类
*
* @author yuki
*
*/
public class Demo {

// 程序的入口
public static void main(String[] args) {

// 一共41个人
final int N = 41;

// 新建一个具有41条边的正多边形
Ring r = new Ring(N);

// 记录当前生存的人数
int i = N;
// 生存人数为零就结束循环
while(i != 0){
// 调用环的报数方法,返回真说明有点死亡,返回假说明无点死亡
if( r.call() ){
// 打印当前存活人数
$("Survival : " + --i);
}
}

}

/**
* 打印语句的封装
* @param s
*/
private static void $(String s){
System.out.println("---------------------------" + s);
}

}

/Josephus/src/com/kodoyang/Josephus/Vertex.java

定义将要循环自杀的犹太人的类


package com.kodoyang.Josephus;
/**
* 构成环的顶点,它是可以不依赖于环独立存在的
*
* @author yuki
*
*/
public class Vertex {

// 唯一标识,会被构造方法初始化
private int id;
// 当前点所处的状态
private boolean dead;

/**
* 构造方法
* @param id
*/
public Vertex(int id){
this.id = id;
}

/**
* 点被环调用了
* @param num 环让它报的数
* @return
*/
public void act(int num) {
// 报数
System.out.println("id = " + id + ", num = " + num);
// 如果报的数是2
if(num == 2){
// 当前点死亡
System.out.println("......I am dead......");
// 设置当前点的死亡状态
dead = true;
}
}

/**
* 返回当前点的死亡状态
* @return
*/
public boolean isDead() {

return dead;
}

}

/Josephus/src/com/kodoyang/Josephus/Ring.java

定义犹太人轮流报数的环的类


package com.kodoyang.Josephus;

/**
* 这是一个报数的环,它由数组实现
* 在对象实例化的时候确定了点的个数,不在改变
*
* 它由一个个的点拼接而成
* pos用来记录当前点的位置,num用来记录当前报出的数字
*
* @author yuki
*
*/
public class Ring {

// 它由一个个的点拼接而成
private Vertex[] vers;
// 记录当前点的位置
private int pos;
// 记录当前报出的数字
private int num;

/**
* 构造方法
* @param n 环拥有的节点数
*/
public Ring(int n){
// 创建构成环的点的数组
vers = new Vertex[n];
// 初始化点的数组
for(int i = 0; i < vers.length; ++i){
// 点的构造方法必须接受一个表示点的id的参数
Vertex ver = new Vertex(i);
// 把点初始化给数组的第i个位置
vers[i] = ver;
}
// 构造完毕并不能让他马上进入报数状态,所以设报数值为-1
num = -1;
}

/**
* 报数
* @return 返回true表示有点死亡,否则没有点死亡
*/
public boolean call(){

// 执行,如果当前的位置不在死亡状态就跳出循环
do {
// 获得下一个位置,如果下一个位置是末尾就设为0, 其它情况加1
pos = pos == vers.length - 1 ? 0 : pos + 1;
} while( vers[pos].isDead() );

// 获得下一个要报的数,如果下一个位置是2就设为0, 其它情况加1
num = num == 2 ? 0 : num + 1;
// 让点报数
vers[pos].act(num);
// 当点报出的数为2时,说明报数的点死亡了
return num == 2;
}

}

运行结果如下:


id = 1, num = 0
id = 2, num = 1
id = 3, num = 2
......I am dead......
---------------------------Survival : 40
id = 4, num = 0
id = 5, num = 1
id = 6, num = 2
......I am dead......
---------------------------Survival : 39
id = 7, num = 0
id = 8, num = 1
id = 9, num = 2
......I am dead......
---------------------------Survival : 38
id = 10, num = 0
id = 11, num = 1
id = 12, num = 2
......I am dead......
---------------------------Survival : 37
id = 13, num = 0
id = 14, num = 1
id = 15, num = 2
......I am dead......
---------------------------Survival : 36
id = 16, num = 0
id = 17, num = 1
id = 18, num = 2
......I am dead......
---------------------------Survival : 35
id = 19, num = 0
id = 20, num = 1
id = 21, num = 2
......I am dead......
---------------------------Survival : 34
id = 22, num = 0
id = 23, num = 1
id = 24, num = 2
......I am dead......
---------------------------Survival : 33
id = 25, num = 0
id = 26, num = 1
id = 27, num = 2
......I am dead......
---------------------------Survival : 32
id = 28, num = 0
id = 29, num = 1
id = 30, num = 2
......I am dead......
---------------------------Survival : 31
id = 31, num = 0
id = 32, num = 1
id = 33, num = 2
......I am dead......
---------------------------Survival : 30
id = 34, num = 0
id = 35, num = 1
id = 36, num = 2
......I am dead......
---------------------------Survival : 29
id = 37, num = 0
id = 38, num = 1
id = 39, num = 2
......I am dead......
---------------------------Survival : 28
id = 40, num = 0
id = 0, num = 1
id = 1, num = 2
......I am dead......
---------------------------Survival : 27
id = 2, num = 0
id = 4, num = 1
id = 5, num = 2
......I am dead......
---------------------------Survival : 26
id = 7, num = 0
id = 8, num = 1
id = 10, num = 2
......I am dead......
---------------------------Survival : 25
id = 11, num = 0
id = 13, num = 1
id = 14, num = 2
......I am dead......
---------------------------Survival : 24
id = 16, num = 0
id = 17, num = 1
id = 19, num = 2
......I am dead......
---------------------------Survival : 23
id = 20, num = 0
id = 22, num = 1
id = 23, num = 2
......I am dead......
---------------------------Survival : 22
id = 25, num = 0
id = 26, num = 1
id = 28, num = 2
......I am dead......
---------------------------Survival : 21
id = 29, num = 0
id = 31, num = 1
id = 32, num = 2
......I am dead......
---------------------------Survival : 20
id = 34, num = 0
id = 35, num = 1
id = 37, num = 2
......I am dead......
---------------------------Survival : 19
id = 38, num = 0
id = 40, num = 1
id = 0, num = 2
......I am dead......
---------------------------Survival : 18
id = 2, num = 0
id = 4, num = 1
id = 7, num = 2
......I am dead......
---------------------------Survival : 17
id = 8, num = 0
id = 11, num = 1
id = 13, num = 2
......I am dead......
---------------------------Survival : 16
id = 16, num = 0
id = 17, num = 1
id = 20, num = 2
......I am dead......
---------------------------Survival : 15
id = 22, num = 0
id = 25, num = 1
id = 26, num = 2
......I am dead......
---------------------------Survival : 14
id = 29, num = 0
id = 31, num = 1
id = 34, num = 2
......I am dead......
---------------------------Survival : 13
id = 35, num = 0
id = 38, num = 1
id = 40, num = 2
......I am dead......
---------------------------Survival : 12
id = 2, num = 0
id = 4, num = 1
id = 8, num = 2
......I am dead......
---------------------------Survival : 11
id = 11, num = 0
id = 16, num = 1
id = 17, num = 2
......I am dead......
---------------------------Survival : 10
id = 22, num = 0
id = 25, num = 1
id = 29, num = 2
......I am dead......
---------------------------Survival : 9
id = 31, num = 0
id = 35, num = 1
id = 38, num = 2
......I am dead......
---------------------------Survival : 8
id = 2, num = 0
id = 4, num = 1
id = 11, num = 2
......I am dead......
---------------------------Survival : 7
id = 16, num = 0
id = 22, num = 1
id = 25, num = 2
......I am dead......
---------------------------Survival : 6
id = 31, num = 0
id = 35, num = 1
id = 2, num = 2
......I am dead......
---------------------------Survival : 5
id = 4, num = 0
id = 16, num = 1
id = 22, num = 2
......I am dead......
---------------------------Survival : 4
id = 31, num = 0
id = 35, num = 1
id = 4, num = 2
......I am dead......
---------------------------Survival : 3
id = 16, num = 0
id = 31, num = 1
id = 35, num = 2
......I am dead......
---------------------------Survival : 2
id = 16, num = 0
id = 31, num = 1
id = 16, num = 2
......I am dead......
---------------------------Survival : 1
id = 31, num = 0
id = 31, num = 1
id = 31, num = 2
......I am dead......
---------------------------Survival : 0

更多好文请关注:http://www.cnblogs.com/kodoyang/

时间: 2025-01-17 09:03:19

约瑟夫环 --- 面向对象 --- java代码的相关文章

约瑟夫环问题 java代码实现(高效率)

问题来历编辑 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而Josephus 和他的朋友并不想遵从.一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是

约瑟夫环问题-Java数组解决

约瑟夫环问题说的是,n个人围成一圈,从第k个人开始沿着一个方向报数,报到第m个人时,第m个人出列,从紧挨着的下一个人(未出列)开始,求整个环中人的出列顺序.下面是我用java实现的解决方法. 1 class JosephLoop 2 { //n为环中人数,m为每次报数的人数,k为报数的起始位置0-n 3 int n,m,k; 4 int[] persons; 5 int[] seq; 6 7 JosephLoop(int n, int k, int m){ 8 this.n = n; 9 thi

约瑟夫环的java解决

总共3中解决方法,1.数学推导,2.使用ArrayList递归解决,3.使用首位相连的LinkedList解决 import java.util.ArrayList; /** * 约瑟夫环问题 * 需求:n个人围成一圈,从第一个人开始报数,数到K的人出局,然后从下一个人接着报数,直到最后一个人,求最后一个人的编号 * @author Miao * */public class Josephus { public static void main(String[] args) { int n =

面向对象---java代码块

概念:代码块是指用{}括起来的一段代码. 根据位置及声明的关键字不同,代码块可分为普通代码块.构造块.静态代码块.同步代码块4种. 1.普通代码块: 直接在方法中或在语句中定义 public class Test2 { public static void main(String[] args) { { //定义普通代码块 int x = 30; //定义局部变量 System.out.println("普通代码块 x="+x); } int x = 100; //与局部变量名称相同

(java描述)关于链表的代码-----单双、循环链表、约瑟夫环、多项式相加

将链表头尾倒置 将几个链表合并成一个新的链表,将链表中重复的节点去掉,并按大小排序 双向循环链表 单向循环链表(约瑟夫循环) 多项式相加 程序源代码 单链表.单向循环链表结点类 package javab; public class Node { int data; Node next; public Node(int data){ this.data=data; } } 第一题代码: package javab; import java.util.Scanner; public class I

约瑟夫环 java实现

问题: N个人从1到N编号,围城一圈,从1开始报数, 数到X时,将X的编号输出,并将那个人踢出, 下一个从1再开始报数,直到所有人都出去 思路: 就是计数,移除,没有太深的思想,直接上代码: package test; import java.util.ArrayList; import java.util.List; import java.util.Scanner; /** * N个人从1到N编号,围城一圈, * 从1开始报数, 数到X时,将X的编号输出,并将那个人踢出, * 下一个从1再开

j使用数组实现约瑟夫环 java

我们首先来看一下约瑟夫环问题: 给定m个人,m个人围成一圈,在给定一个数n,从m个人中的第一个人每第n个人便将其除去,求被最后一个出去的人的编号. 思路: 建立一个长度为m+1的数组,将其的内容初始化为0至m 我们设置变量i与j,i代表数组元素的下表,因为我设置的数组长度为m+1,所以数组下标就为每个人的编号,当i==m的时候,我们将i置为0,让其从头开始便利. 变量j为判断当前元素是否为排列的第n个元素,如果是则将当前下标为i的元素的值置为0,不是的话,i++,j++,每当我们遍历到数值为0的

约瑟夫问题的JAVA实现(借鉴别人的代码+自己分析理解)

http://www.blogjava.net/rorely/archive/2010/01/15/309732.html 原博客地址 import java.util.Scanner; /** *使用数组实现约瑟夫环问题 *由m个人围成一个首尾相连的圈报数. *从第一个人开始,从1开始报数,报到n的人出圈, *剩下的人继续从1开始报数,直到所有的人都出圈为止. *对于给定的m和n,求出所有人的出圈顺序. */ public class RingYuesefu{ public static vo

Java学习之约瑟夫环的两中处理方法

1 package day_2; 2 3 import java.util.Scanner; 4 5 /** 6 * @author Administrator 7 * 约瑟夫环问题: 设编号为 1,2,3,....n的N个人围坐一圈,约定编号为k(1<=k<=n) 8 * 的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次 9 * 类推,直到所有人出列为止,由此产生一个出队编号的序列. 10 * 方法一:数组取模法.(模拟) 11 */ 12 13 p