Java 数组实现约瑟夫环


思路

1.把人的序号写入数组里
2.然后通过key找到要被杀的人在数组里的下标
3.打印那个人序号
4.然后如果那个数不是有效数组的最后一个,要将这个数后面的数前移,即整个数组前面部分都是没有被处理过的,而后面的都是无意义的数,前面的是有效的
5.这样我们假装数组在不断变短,用n来标记最后一个(n-1)

 

带注释版

public class yuesefu 
{
	public static void main(String[] args) 
	{
		int N=5,S=1,D=2;  //N总数、S第一次在哪儿开始数、D数几次
		int n=N;     //n是剩下的人数 
		int []a=new int [N];  //用数组存储人的序号
		for(int i=0;i<a.length;i++)  //数组赋值1、2……
		{
			a[i]=i+1;
		}
		int key=(S+D-2)%n;//key是第一次简化后应该被显示出来的数组下标,S+D-1是个数,再减1就是那个数的下标
		for(int i=1;i<=N-1;i++) //循环N-1次取出N-1个那么只剩1个了,即剩下被赦免那个
		{  
			System.out.print(a[key]+"\t");   //把要取出的人显示出来
			if(key<n-1)   //如果取出的数不是最后一个,要把这个数后面的数前移
			{
				for(int j=key;j<=n-2;j++)//这里用覆盖的方法,比如取出的数是a[2],那么将a[3]、a[4]……向前覆盖
				{      //假如覆盖3次以后,那么数组最后面的3个数是没有实际意义的,就不必向前覆盖,即前移到n-2
					a[j]=a[j+1];  //j<=n-2是因为 a[j]=a[j+1];即最后会是a[n-2]=a[n-1];最后一个位置没有意义
				}
			}
			n--;//将人数减少,数组是不变的,但是数组后面无意义的数就不算了,即假装数组在变短,数组只有前面有意义
			key=(key+D-1)%n; //这里更新下一个应该被取出的数在数组里的下标
		}
		System.out.print(a[0]); //输出最后一个数,即被赦免的数,而且a[1]、a[2]……在我们看来没意义了
	}
	
}

 

 

不带注释

 

 

public class yuesefu 
{
	public static void main(String[] args) 
	{
		int N=5,S=3,D=4;
		int n=N;
		int []a=new int [N];
		for(int i=0;i<a.length;i++)
		{
			a[i]=i+1;
		}
		int key=(S+D-2)%n;
		for(int i=1;i<=N-1;i++)
		{
			System.out.print(a[key]+"\t");
			if(key<n-1)
			{
				for(int j=key;j<=n-2;j++)
				{
					a[j]=a[j+1];
				}
			}
			n--;
			key=(key+D-1)%n;
		}
		System.out.print(a[0]);
	}
	
}

    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/brucefuu/article/details/40474767
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞