Josephus问题的java实现
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner; public class Josephus { public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m, n;
m = sc.nextInt();
n = sc.nextInt();
pass(m, n); // 注意这里的m为传递次数,要与报数次数区分开.即:传递次数 = 报数次数-1.
} public static void pass(int m, int n)
{
int i, j, mPrime, numLeft;
ArrayList<Integer> L = new ArrayList<Integer>();
// 为队列中的成员编号:从1~n
for (i=1; i<=n; i++)
L.add(i);
// 初始化各个元素
ListIterator<Integer> iter = L.listIterator();
Integer item=0;
numLeft = n;
mPrime = m % n;
// 进行n此循环,每次删除一个成员
for (i=0; i<n; i++)
{
mPrime = m % numLeft;
if (mPrime <= numLeft/2) // 当mPrime小于剩余人数的一般时,进行正移。(向后移next)
{
if (iter.hasNext())
item = iter.next();
for (j=0; j<mPrime; j++)
{
if (!iter.hasNext())
iter = L.listIterator();
item = iter.next();
}
}
else
{
for (j=0; j<numLeft-mPrime; j++) // 当mPrime大于剩余的一般人数时,进行反移。(向前移previous)
{
if (!iter.hasPrevious())
iter = L.listIterator(L.size());
item = iter.previous();
}
}
System.out.print("Removed " + item + " ");
iter.remove();
if (!iter.hasNext())
iter = L.listIterator();
System.out.println();
for (Integer x:L) // 利用增强for循环遍历表
System.out.print(x + " ");
System.out.println();
numLeft--;
}
System.out.println();
}
}
对于Josephus问题有两个地方是可以进行优化的。 (总人数为N,编号为从0~N-1;经过M次报数去除一个成员,剩余成员个数为numleft, 记M%numleft为mPrime)
1、被移除的成员与上一个成员之间的距离是M%numleft-1(报数次为M%numleft).当M大于N时,该计算方式将节省大量时间
2、当mPrime大于numleft的时候可以反向遍历该表来查找要去除的成员。这样可以节省时间。同样这也就要求了该表必须是一个双向表才行。(即含有Previous方法)
该算法实现原理即为:
第一轮,必定为编号M%N-1的成员被去除,第二轮为在第一轮的基础上即从编号为M%N的成员开始正移mPrime-1个单位(或者反移numleft-mPrime-1个单位)。若将M%N即为编号0,开始重新编号,那么第二轮被删除的成员编号便是M%(numleft)-1,由此可得该轮要被删除的成员与上一轮去除成员之间的距离为M%numleft,这里可利用迭代器来实现。
这里我们便可以得到成员编号与该轮成员数目的关系是:(n表示该轮所剩余的成员数目,Index(n)表示该轮成员的编号(从0开始))
Index(n) = (Index(n - 1) + m) % n。
该算法的详细解析与其他方式的实现可参见文章:
Josephus问题的不同实现方法与总结
Josephus问题的java实现的更多相关文章
- Josephus问题的不同实现方法与总结
/************************************************************************/ /* Josephus问题--数组实现 */ /* ...
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Josephus环类问题,java实现
写出一个双向的循环链表,弄一个计数器,我定义的是到三的时候,自动删除当前节点,很简单. package Com; import java.util.Scanner; /* * 约瑟夫环问题,有n个人组 ...
- Josephus Problem的详细算法及其Python、Java实现
笔者昨天看电视,偶尔看到一集讲述古罗马人与犹太人的战争--马萨达战争,深为震撼,有兴趣的同学可以移步:http://finance.ifeng.com/a/20170627/15491157_0. ...
- Josephus问题Java实现
package com.qingfeng; /** * @author Administrator * 功能:约瑟夫问题: * 设编号分别为:1,2,...,n的n个人围坐一圈. * 约定序号为k(1 ...
- [Java]使用队列求解josephus问题
约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环. 有个囚犯站成一个圆圈,准备处决.首先从一个人开始,越过个人(因为第一个人已 ...
- Java实现约瑟夫环
什么是约瑟夫环呢? 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...
- 约瑟夫问题(java实现)
方法一.自定义的链表实现 package com.code.yuesefu; public class YueSeFuList { public static void main(String[] a ...
- java编程题
第一题:输入字符串长度len1,字符串s1,字符串长度len2,字符串s2.从后向前比较,以最短字符串为标准,输出不同的元素的个数. 例如: 输入:s1="1,3,5" ...
随机推荐
- ARM处理器简介
参考: http://www.arm.com/zh/products/processors/instruction-set-architectures/index.php 1.ARM核演变图 2.AR ...
- LDA 线性判别分析
LDA, Linear Discriminant Analysis,线性判别分析.注意与LDA(Latent Dirichlet Allocation,主题生成模型)的区别. 1.引入 上文介绍的PC ...
- iOS 之 导航栏按钮
UIButton *releaseButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [releaseButton setTitle ...
- plupload 异步上传插件使用心得
plupload 可以不依赖jquery,并且提供了 html5,flash,silverlight,html4 多种上传模式,使用起来比较简单,上一篇博客中介绍了其主要参数哈函数 一.简化用法 &l ...
- PHP数组函数的分组归纳
统计: array_count_values 统计数组中所有的值出现的次数 array_product 计算数组中所有值的乘积 array_sum 计算数组中所 ...
- Android Studio快捷键汇总
- Struts2框架学习(三) 数据处理
Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:Value ...
- Struts2的拦截器----Dog实例
拦截器是一个类,这个类包含方法,用来解决DRY规则,即代码复用的问题.如果不调用拦截器,代码中需要显示通过代码调用目标方法,定义了拦截器,系统就会自动执行.大部分时候,拦截器方法都是通过代理的方式调用 ...
- redis 实例
打redis模块打开官网 http://www.redis.io/ 进入clients 找到PHP的选项 然后进入phpredis 这就是redis for php的扩展模块 phpize ./co ...
- HDU-1754-I Hate It(线段树,简单,不过好像有点问题)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1754 题目不难,不过开始我犯了一个低级错误,输入n,m,m代表操作的数目,我没有写了,写代码的时候,就 ...