约瑟夫问题(一)
这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
*问题分析与算法设计
约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。
题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。这个是愿意。
现在的衍生问题
就是说有n个人围成一圈,然后说从任意指定的一个
人那里为起点,以m个人为单位,每转m个人第m个人被杀死。当起始人也就是所谓的
第1个人是最后被杀死的,这个m就是为所求,满足这样就叫joseph问题。
然后带一个递归实现
学习代码
/*
* 作者:
* 功能:丢手帕问题
*/
public class Josiefu {
public static void main(String args[])
{
CycLink cyclink=new CycLink();
cyclink.setLen(9);
cyclink.createLink();
cyclink.setK(2);
cyclink.setM(2);
cyclink.show();
cyclink.play();
}
}
class Child
{
int no;
//创建第一个小孩的引用不能动
Child nextChild=null;
public Child(int no)
{
this.no=no;//给一个编号
}
}
class CycLink
{// 先定义一个指向链表第一个小孩的引用
Child firstchild=null;
Child temp=null;
int len=0;//表示小孩子的个数
int k=0;
int m=0;
//设置链表的大小
public void setLen(int len)
{
this.len=len;
}
//初始化环形链表
public void createLink()
{
for(int i=1;i<=len;i++)
{
if(i==1){//创建第一个小孩
Child ch=new Child(i);
this.firstchild=ch;
this.temp=ch;
}else
{
//创建最后的一个小孩
if(i==len){
Child ch=new Child(i);
temp.nextChild=ch;
temp=ch;
temp.nextChild=this.firstchild;
}else{
//继续创建小孩
Child ch=new Child(i);
temp.nextChild=ch;
temp=ch;
}
}
}
}
//设置从第几个人开始数数
public void setK(int k)
{
this.k=k;
}
public void setM(int m){
this.m=m;
}
//开始Play
public void play()
{ Child temp=this.firstchild;
//1.先找到开始数数的人
for(int i=1;i<k;i++)
{
temp=temp.nextChild;
}
//2.数m下
while(this.len!=1){
for(int j=1;j<m;j++)
{
temp=temp.nextChild;
}
//找到要出圈的前一个小孩
Child temp2=temp;
while (temp2.nextChild!=temp)
{
temp2=temp2.nextChild;
}
//3.将数到m的小孩,退出圈
temp2.nextChild=temp.nextChild;
//让temp指向下一个数数的小孩
temp=temp.nextChild;
//this.show();
this.len--;
//
}//最后一个小孩
System.out.println("最后出圈:"+temp.no +"");
}
//打印该环形链表
public void show()
{
//定义一个跑龙套
Child temp=this.firstchild;
do{
System.out.println(+temp.no+" ");
temp=temp.nextChild;
}while(temp!=this.firstchild);
}
}
遇到的问题有
java.lang.NullEception的错误,因出现了空指针,把初始化的child的第一个孩子指向了空。出现异常。修改
把初始化的方法中的创建的对象ch的值赋给第一个孩子。
还有//this.show()这个方法出现在循环中出现了死循环!