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

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。

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值