Joseph问题求解。(用java求解约瑟夫问题)

import java.util.ArrayList;
import java.util.Random;
/*Joseph问题求解。
Joseph问题:
编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。

算法:
1、初始化:给每个人设置一个标志bOut,表示这个人是否已经出局了。初值为false表示没有出局。
2、设置一个变量Outcounter,表示已经出局的人数。初值为0表示开始没有人出局。
3、若OutCounter达到所有人数n,则退出程序。
4、顺序判断每个人的出局标志bOut,若这个人出局了(bOut==true),则重复本步骤,判断下一个人是否已经出局。
5、若这个人没有出局(bOut==false),则判断m是否达到最大值。
6、若m达到最大值,则输出这个人的序号并设置这个人的出局标志(bOut=true),m=这个人的密码,已出局人数增加1,即Outcounter++。
7、若m没有达到最大值,则m增加1,转3
本例用ArrayList实现。
*/

class person
{
 public int id;
 public int password;
 public boolean bOut;//表示该元素是否已经退出,bOut=true表示已经退出,bOut=false表示没有退出
 person()
 {
  id=0;
  password=0;
  bOut=false;
 }
 person(int id,int password)
 {
  this.id=id;
  this.password=password;
  bOut=false;//
 }
}

public class Joseph
{
 public static void main(String[] args)
 {
  int Outcounter=0;//退出的人计数,每退出一个人,增加1
  ArrayList al=new ArrayList();
  Random rand=new Random();
  int m=0;
  if (args.length==2)//若给定两个参数n,m,则用来初始化ArrayList,每个人的密码随机生成1~n。
  {
   m = Integer.parseInt(args[1]);
   for (int i=0; i<Integer.parseInt(args[0]); i++)
   {
    al.add(new person(i,rand.nextInt(Integer.parseInt(args[0]))+1));
   }
  }
  else//未给任何参数,则默认设定10人,每个人的密码都是5。
  {
   m=5;
   for (int i=0; i<10; i++)
   {
    al.add(new person(i,5));
   }
  }
  for (int i=0; i<al.size(); i++)      System.out.println("id="+((person)al.get(i%al.size())).id+",password="+((person)al.get(i%al.size())).password+",bOut="+((person)al.get(i%al.size())).bOut);
  System.out.println("----------------------------");

  int j=0;
  for (int i=0; Outcounter<al.size(); i++)
  {
//   System.out.println("j="+j+",m="+m);
   if (((person)al.get(i%al.size())).bOut==false)
   {
    if (j==m)
    {
     System.out.println("id="+((person)al.get(i%al.size())).id+",password="+((person)al.get(i%al.size())).password+",bOut="+((person)al.get(i%al.size())).bOut);
     ((person)al.get(i%al.size())).bOut=true;
     m=((person)al.get(i%al.size())).password;
     j=0;//设置m之后,j归零以便从下一个人重新开始向新的m计数。
     Outcounter++;
     continue;
    }
    else
    {
     j++;
     continue;
    }
   }
  }//end for
 }//end main()
}//end class Joseph

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值