博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法笔记_029:约瑟夫斯问题(Java)
阅读量:6438 次
发布时间:2019-06-23

本文共 2187 字,大约阅读时间需要 7 分钟。

目录

 


1 问题描述

引用自《算法设计与分析基础》第三版:

约瑟夫斯问题,是以弗拉瓦斯。约瑟夫斯(Flavius Josephus)的名字命名的。约瑟夫斯是一个著名的犹太历史学家,参加并记录了公元6670年犹太人反抗罗马的起义。约瑟夫斯作为一个将军,设法守住了裘达伯特的堡垒达47天之久,但在城市陷落了以后,他和40名顽强的将士在附近的一个洞穴中避难。在那里,这些反抗者表决说“要投降毋宁死”。于是,约瑟夫斯建议每个人应该轮流杀死他旁边的人,而这个顺序是由抽签决定的。约瑟夫斯有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说服了他原先的牺牲品一起投降罗马。

 

上述是约瑟夫斯问题的起源,看完后个人感觉有点抽象,其实约瑟夫斯问题的本质为:n个人(编号由 1,2, ..., n)围成一圈,由编号为1的人从1开始报数,报到k的退出自杀,剩下的人继续从1开始报数,直到圈内只剩余1人,求胜利者的编号。(n>0, k>0)  

例如:

n个人编号:

1  2  3  4 ... ... n-1  n

现在进行报数:

1  2  3  4... k(出列自杀)  1  2  ...(循环报数,当到达编号为n的人时,下一个报数的从编号为1的人开始进行)

 

 


2 解决方案

约瑟夫斯问题的核心即找出给定n个人从前到后的自杀顺序,最后一个将要进行自杀的人即为幸存者。

具体编码如下:

package com.liuzhen.chapter4;import java.util.Scanner;public class JosephProblem {    /*     * 参数n:给定总人数     * 参数k:报数为k的人出列     * 函数功能:返回n个人从前到后的自杀顺序     */    public int[] getKillOrder(int n,int k){        int[] result = new int[n];        int[] man = new int[n];        for(int i = 0;i < n;i++)            man[i] = i+1;     //给n个人编号,编号分别为1~n        int count = 0;        //用于计算当前已经自杀的人数        int pos = -1;         //用于记录遍历数组man当前下标        int tempK = 0;        //用于计算报数大小,一旦tempK = k,则喊到k的人出列        while(count < n){            pos = (pos+1)%n;         //遍历过程中,会出现环列,取余可以除去环的影响            if(man[pos] != 0)  //man[pos] == 0,表示此人已自杀                tempK++;            if(tempK == k){                result[count++] = man[pos];  //记录当前自杀人的编号                man[pos] = 0;                tempK = 0;            }        }        return result;    }        public static void main(String[] args){        JosephProblem test = new JosephProblem();        Scanner in = new Scanner(System.in);        System.out.println("请输入约瑟夫斯问题的总人数n:");        int n = in.nextInt();        System.out.println("请输入约瑟夫斯问题的报数设定值k:");        int k = in.nextInt();        int[] result = test.getKillOrder(n,k);        System.out.println("共"+n+"人,依次报数,当报到"+k+"的人自杀,其自杀顺序为:");        for(int i = 0;i < result.length;i++)            System.out.print(result[i]+"  ");    }}

运行结果:

请输入约瑟夫斯问题的总人数n:6请输入约瑟夫斯问题的报数设定值k:2共6人,依次报数,当报到2的人自杀,其自杀顺序为:2  4  6  3  1  5  请输入约瑟夫斯问题的总人数n:7请输入约瑟夫斯问题的报数设定值k:2共7人,依次报数,当报到2的人自杀,其自杀顺序为:2  4  6  1  5  3  7  请输入约瑟夫斯问题的总人数n:10请输入约瑟夫斯问题的报数设定值k:3共10人,依次报数,当报到3的人自杀,其自杀顺序为:3  6  9  2  7  1  8  5  10  4

 

参考资料:

     1.

转载地址:http://qazwo.baihongyu.com/

你可能感兴趣的文章
ExcelJS —— Node 的 Excel 读写扩展模块2
查看>>
《数字短片创作(修订版)》——第一部分 剧本创作 第1章 数字短片创意技法 剧本创作的构思...
查看>>
MIT 学生挑战新泽西索取挖矿程序源代码的要求
查看>>
实践 | 不同行业WMS选型策略及需要注意的一些问题
查看>>
MaxCompute与OSS非结构化数据读写互通(及图像处理实例)
查看>>
【F3简介】一张图看懂FPGA-F3实例
查看>>
bash环境(变量与bash配置文件)
查看>>
Server Hard drive mode
查看>>
smb服务器配置过程遇到错误及解决
查看>>
java杂乱
查看>>
在Linux上安装Python3.6.1
查看>>
[基础]iOS 可视化编程(全系列)
查看>>
我的友情链接
查看>>
LVS之NAT模型配置实验
查看>>
nginx 报错 99: Cannot assign requested address
查看>>
几种流行的AJAX框架:jQuery,Mootools,Dojo,Ext JS的对比
查看>>
Socket-Client通信
查看>>
Maven搭建简单的SS项目
查看>>
#我要上首页# 新版博客首页来了,做明星博主还会远吗?
查看>>
PHP缓存技术
查看>>