利用数组模拟的链表解决Josephus问题

来源:互联网 发布:淘宝网小提琴 编辑:程序博客网 时间:2024/06/06 02:27

1.什么是Josephus问题

       什么?!你还不知道什么是Josephus问题?太out了吧。

       就是有n个人未作在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列,如此反复,直到所有的人全部出列为止。Josephus问题是:对于任意给定的n、s、m,求出按出列次序得到的n个人员的序列。

       在这里,我们先来做一个简单的例子,在这个简单的例子的基础上,再去解决Josephus问题,那么会简单好多,有兴趣可以借鉴我的方法去实现,我这里主要是向大家展示数组模拟的链表。

       我们做的简单的例子是求的什么呢?就是剩下的最后一个人的索引,而且s为1.

2.解决思路

       利用上篇我说道的数组模拟链表,首先先建一个长度为n的数组。当数到m-1时,修改第m-1的值为第m+1,这样指向m的索引就没有了,m也就被“删除”了。

       如此循环,当循环到某索引出的值,等于此处的索引时,那么也就是这个数组剩下“最后一个”元素。由于数组模拟的链表不是真正的删除,这点我们在这线不讨论了。

3.说的好不如代码敲得好,代码能够说明一切

 

/**作者:曹建新*实现功能:利用数组模拟链表解决。。问题*参数:第一个参数为n,第二个参数m*/        class ArrayList{public static void main(String[] args) {//判断用户是否给出参数//如果没有给出2个,则提示然后退出,否则继续if(args.length!=2){System.out.println("You must give two argument!");System.exit(0);}//System.out.println(("123").matches("[0-9]*")); //判断给的两个参数是否都是可以转换为数字//如果两个参数中有一个不是,则提示,然后退出,否则继续for(int i=0; i<args.length; i++){if( !args[i].matches("[0-9]*")) {System.out.println("Two argument must be Number!");System.exit(0);}}//利用给出的参数进行数组的初始化int[] a=new int[Integer.parseInt(args[0])];for (int i=0; i<a.length-1; i++){a[i]=i+1;}a[a.length-1]=0;int index=0;//用来存储当前位置int countNum=0;//用来计数//测试数组是否赋值成功/*for(int i=0; i<a.length; i++){System.out.println(a[index]);index=a[index];}*///当某索引中的值与索引相同时,说明只剩下一个了while(a[index] !=index ){countNum ++;//判断是否应该有人退出//要改数到的那个同学的上一位,所以需要-1//删除,就是把前一个索引处的值改成当前索引所对应的值if (countNum==Integer.parseInt(args[1])-1){a[index]=a[a[index]];countNum=0;}index=a[index];//设置下一个索引为当前索引对一个的值}System.out.println(index);}}


       写个博客,换了好几台电脑,现在用的不是我电脑,没有java运行环境,就不给大家贴调用的结果了,给大家写一下调用的方法吧。java ArrayList 10 3,结果为3。

       代码中的注释写的很详细,哪有错误和不明白的地方都可以说出来,大家一起进步。另外,这个思路是面向过程的思路写的,也欢迎大家用面向对象的思路写一下,然后给我发一个链接,我回很认真的拜读。