约瑟夫问题 java 实现
约瑟夫问题
这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,数到第九个人就将他扔入大海。该人后面的人从1开始重新报数,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
思路
1. 先建立一个类,有 id 和 isRemove
class Person {int id;boolean isRemove;public Person(int id, boolean isRemove) {this.id = id;this.isRemove = isRemove;}public boolean isRemove() {return isRemove;}public void setRemove(boolean isRemove) {this.isRemove = isRemove;}
}
- 2.
class Circle {private ArrayList<Person> circle = new ArrayList<Person>();private int amount; // 一共多少人Circle(int amount) {this.amount = amount;for (int i = 0; i < amount; i++) {Person p = new Person(i + 1, false);circle.add(p);}}/*** * @param index* 最开始扔人的位置,比如第9人* @param total* 共需要扔几次*/public void getIndex(int index, int total) {// 起始位置int currentIndex = -1;for (int t = 0; t < total; t++) {int notRemove = 0;//本来是notRemove != 9,写死不好while (notRemove != index) {currentIndex++;// 或者用 currentIndex % amount 解决if (currentIndex == amount) {currentIndex = 0;}if (!circle.get(currentIndex).isRemove) {notRemove++;}}// 将扔的人设为 truePerson p = circle.get(currentIndex);p.setRemove(true);circle.set(currentIndex, p);System.out.printf("第 %-2d 次仍的人id是%4d\n", t + 1, p.id);}}}
代码建立一个容器来保存各个人,主要就是不移除这个人,而是把他状态设为setRemove(true),好处这样容器的大小保持不变。如果删掉这样人,容器大小每次减1,算起来麻烦
if (currentIndex == amount) {currentIndex = 0;
}
本来是用 currentIndex % amount 实现的,不过本代码都是+1,肯定会有 == amount的情况,用置为0更好
结果
第 1 次仍的人id是 9
第 2 次仍的人id是 18
第 3 次仍的人id是 27
第 4 次仍的人id是 6
第 5 次仍的人id是 16
第 6 次仍的人id是 26
第 7 次仍的人id是 7
第 8 次仍的人id是 19
第 9 次仍的人id是 30
第 10 次仍的人id是 12
第 11 次仍的人id是 24
第 12 次仍的人id是 8
第 13 次仍的人id是 22
第 14 次仍的人id是 5
第 15 次仍的人id是 23
优化
也可以用数组实现,下标和 boolean 正好模拟上面的 Person 类
static void other() {boolean[] usaJapa = new boolean[30];// 用类库初始化Arrays.fill(usaJapa, true);int leftCount = usaJapa.length;int countNum = 0;int index = 0;int i = 0;while (leftCount > 15) {if (usaJapa[index]) {countNum++;}if (countNum == 9) {countNum = 0;usaJapa[index] = false;leftCount--;System.out.printf("第 %-2d 次仍的人id是%4d\n", ++i, index + 1);}index++;if (index == usaJapa.length) {index = 0;}}}
用链表实现,remove 其中的数据
class Circle {private LinkedList<Person> circle = new LinkedList<Person>();private int amount; // 一共多少人Circle(int amount) {this.amount = amount;for (int i = 0; i < amount; i++) {Person p = new Person(i + 1, false);circle.add(p);}}public void othergetIndex(int mark, int total) {// remain 是剩下的人数,total 是需要删除的人数int remain = amount;int count = 0;int current = 0;int i = 0;while (remain > amount - total) {count++;// 注意这人如果达到 mark,比如第9个人// 删掉第9个人后,再删第9个人,就是删原来的第10个人if (count == mark) {// remove 返回的是删除的 PersonPerson p = circle.remove(current);System.out.printf("第 %-2d 次仍的人id是%4d\n", ++i, p.id);count = 0;remain--;} else {current++;}if (current == amount - i) {current = 0;}}}
}
用 LinkedList 删除操作更快,
Person p = circle.remove(current);
remove 返回删除的元素
LinkedList<Integer> testList = new LinkedList<Integer>();
for (int i = 0; i < 10; i++) {testList.add(i);
}
for (int i = 0; i < 5; i++) {System.out.println(testList.remove(3));
} /*** 3* 4* 5* 6* 7*/
这段代码的输出可以看出,删除了第3个元素,后面元素往前移动
约瑟夫问题 java 实现相关推荐
- 【每日一题】洛谷--P1996 约瑟夫问题 java题解
文章目录 题目链接 题解 题目链接 洛谷–P1996约瑟夫问题 题解 约瑟夫问题细品一下,就是一个链表成环,根据规则要求逐渐remove的一个思路.代码详解如下: package com.compan ...
- 约瑟夫问题JAVA算法
去年学院举办的算法设计比赛,当时使用的c语言来描述的,而且当时刚刚学了数据结构.于是就用到循环链表来解决,虽然答案没有完全出来,但是评分的老师,看了我的代码和思路,也许是半个感情分,毕竟是学校的算法比 ...
- 约瑟夫环 java代码_约瑟夫环算法的Java实现代码
相信大家都知道这是一个的算法问题,约瑟夫环的c语言实现是利用了指针链表的形式,java实现呢,我的这个是用了内部类. 算法描述:n个人围成一圈,每人有一个各不相同的编号,选择一个人作为起点,然后顺时针 ...
- 约瑟夫环 java实现
曾经一次笔试,由于准备不足,前面所有题都打完了,但是最后一题,就是手写约瑟夫环,我居然没有写出来,然后..凉凉了.. 现在再来回顾一下: 问题:有100个人围成一个圈,从1开始报数,报到14的这个人就 ...
- 约瑟夫问题java 递归_从约瑟夫问题的递归实现的问题说起
在解决约瑟夫问题时,我比较推荐使用递归,因为递归实现的算法代码更短,逻辑也更清晰,然而很多人有一个疑问,那就是他们知道递归层数是有极限的,这就意味着当需要很大层数的递归时,递归算法是不可行的,会导致段 ...
- 约瑟夫问题java代码
public class Josephus {public static void main(String[] args) {//总人数为41int total = 41;MyNode first = ...
- POJ-2746:约瑟夫问题(Java版)
问题描述: 题目要求,这里就不再给出了.大致描述如下:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数.就这样, ...
- 约瑟夫问题(丢手帕问题)的java实现
约瑟夫问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉.例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3.最后剩下1号.借用一些自己感兴趣的球星的名字,使 ...
- java模拟单链表环形链表解决约瑟夫问题
java模拟环形链表解决约瑟夫问题 此文是观看尚硅谷韩老师的数据结构与算法学习视频整理的笔记 约瑟夫问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算 ...
最新文章
- Docker运行sonarqube-(代码质量检测平台)
- 欧拉函数 cojs 2181. 打表
- 使用Spark Shell开发运行Spark程序
- 校企合作与集成电路--华为在行动
- C# datagridview 实现按指定某列或多列进行排序
- web文件被更改crawlergo怎么解决_hscan:一款集成crawlergo和xray的src漏洞挖掘利器
- 涵盖农业、可再生能源、酒店、金融服务、创意服务、科技、林业和建筑业的20家新公司加入《气候宣言》
- 基于matlab的简易诊断系统,基于matlab的图像识别
- 定时任务cron表达式工具
- c++使用librdkafka kerberos认证
- FC经典游戏600合集for mac(小霸王游戏) 中文版
- 我的眼眸,等你路过我的容颜
- Java中抽象类和接口的区别
- Impala 4.0 启用 LZO
- Windows/Linux混合刻录之后,光盘文件不见了?
- IP数据包在网络中的传输过程
- 【IPFS应用开发】ipfs安卓节点编译 ipfs andriod node
- 博德之门 linux x32,GOG.com
- 高斯-克吕格(Gauss-Kruger)投影与UTM投影的在ArcGIS中的区别
- 有机晶体数据库_ChIN简介页:剑桥晶体结构数据库(CSD, 有机、金属有机物)