package com.apache.owen.link.josephus;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
/**
* Josephus环
* 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
*
* @author chenchen
*/
public class Josephus extends TestCase {
public void test() {
findMonkey(50000, 3);
myJosephus(50000, 3, 1);
}
/**
* 使用纯数学方法来解决问题, 原算法未提供参数start
* length=30000000时, 运算时间才会超过1s
* length=200000时, 运算时间才会超过1ms
* step值对运算时间影响不大
* O(1)
* http://blog.csdn.net/MapReduce/archive/2007/04/02/1549494.aspx
* http://hi.baidu.com/wuxyy/blog/item/464471f03802fcafa40f523c.html
* http://hi.baidu.com/sulipol/blog/item/fb18458e5e6346e4f11f366e.html
* @param length 初始化队列的长度
* @param step m
* @param start k
* @return
*/
protected void findMonkey(int length, int step) {
int start = 0;
long startTime = System.currentTimeMillis();
for (int i = 2; i <= length; i++){
start = (start + step) % i;
}
long stopTime = System.currentTimeMillis();
System.out.println("Josephus spend time: " + (stopTime - startTime) + "ms");
System.out.println(start + 1);
}
/**
* 自己完成的方法: java通过模拟实际情况达到解决问题的目的
* step越小, 花的时间越长
* length=40000时, 运算时间会超过1s
* length=5000时, 运算时间会超过1ms
* O(nm)
* @param length
* @param step
* @param start
*/
protected void myJosephus(int length, int step, int start) {
// 存储人员的队列
List<String> list = new ArrayList<String>();
for (int i = 1; i <= length; i++) {
list.add(((Integer) i).toString());
}
// 开始报数的人所在队列中的排数, 初始化current=start-1, current为下标
int current = start - 1;
long startTime = System.currentTimeMillis();
do {
// 从自己开始数数, 所以-1
current += step - 1;
// 当current超过整个队列的实际长度时, 需要回到头继续数
while (current >= list.size()) {
current -= list.size();
}
// 数到m的那个人出列
list.remove(current);
// 继续数数, 直到留下最后的那个人
} while (list != null && list.size() > 1);
long stopTime = System.currentTimeMillis();
System.out.println("Josephus spend time: " + (stopTime - startTime) + "ms");
System.out.println(list.iterator().next());
}
}
分享到:
相关推荐
Josephus环的问题看起来很简单,假设有n个人排成一个圈。从第一个人开始报数,数到第m个人的时候这个人从队列里出列。然后继续在环里数后面第m个人,让其出列直到所有人都出列。求所有这些人出列的排列顺序。
《简单Josephus环模拟器》是一款基于C#编程语言开发的桌面应用程序,它主要用于模拟经典的Josephus问题。Josephus问题源自一个古老的数学问题,通常在博弈论和计算机科学中被用作教学示例。该问题涉及到在一个封闭的...
代码比较清晰 易懂 规范 找了很多从中挑选出来的
2、 约瑟夫(Josephus)环问题:编号为1,2,3,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止。报m...
Java约瑟夫环(Josephus Problem)是一种著名的理论问题,源于古罗马的传说。在问题中,人们站成一个圈,并按照某种顺序依次剔除,最后剩下的人将获得某种奖励或者幸存。Java编程实现约瑟夫环可以采用递归或非递归的...
#include #include #define NULL 0 #include typedef struct Lnode{ int data; struct Lnode *next; }joseph;
"Josephus环问题"是一个经典的理论问题,源自罗马历史学家Flavius Josephus的一个故事。在问题中,人们围成一个圈,按照某种规则报数,每次数到特定数字的人会被淘汰,直到只剩一人为止。这个问题在计算机科学中被...
Josephus问题可以描述为如下的一个游戏:N个人编号从1到N,围坐成一个圆圈,从1号开始传递一个热土豆,经过M次传递后拿着土豆的人离开圈子,由坐在离开的人的后面的人拿起热土豆继续进行游戏,直到圈子只剩下最后一...
Josephus环的四种解法(约瑟夫环)基于java详解 Josephus环是数学应用问题中的一种经典问题,它的解法有多种,今天我们将通过java代码详细介绍Josephus环的四种解法。 问题描述 Josephus环是一个数学应用问题:已知...
java实现约瑟夫环问题Josephus 约瑟夫问题 * 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k(1,2,3...n)的人开始报数,数到m(1,2,3...)的那个人出列; * 他的下一个人又从1开始报数,...
Data Structure 数据结构课,河内环的代码,希望对大家有用!
设有n个人围坐一圈并由1到n编号,从某个人开始报数,数到m的人出列,接着从出列的下一个人开始重新1到n报数,数到m的人又出列,如此反复地报数和出列,直到最后一个人出列为止,设计确定这n个人出列序列的程序
本课程设计的任务是实现一个约瑟夫环(Josephus problem)问题的解决方案,该问题涉及到一系列个体(本题中为编号从1到n的人)围成一个圆圈,并按照特定规则逐一出列,直到所有个体都已出列为止。 **具体要求**: 1...
单链表解决约瑟夫环问题
一开始任选一个整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此...
约瑟夫环,又称约瑟夫问题(Josephus Problem),源自一个古老的传说,它在计算机科学中被用来研究循环链表、递归算法以及组合数学等领域。在这个实习报告中,我们将围绕约瑟夫环的理论、实现和应用进行详尽的探讨。...
用单链表作数据结构实现计算Josephus问题的通用算法。 输入的元素个数为n,从第s个元素开始计数,数到第m个数据出列。
约瑟夫环问题是一个经典的算法问题,也是数据结构中链表操作的一个应用实例。问题起源于一个传说,即犹太历史学家约瑟夫·弗拉维奥在描述一个特定情景时提出的问题。在C++中实现约瑟夫环算法,通常需要借助数组或...
### 约瑟夫环(Josephus)问题详解 #### 一、问题背景与定义 约瑟夫环问题,又称为约瑟夫问题或者约瑟夫斯难题,源自古罗马历史学家弗拉维乌斯·约瑟夫斯的自传。在面对敌人的围攻时,约瑟夫斯和他的40名士兵退守...