A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

由m个人围成一个首尾相连的圈报数。从第一个人开始,从1开始报数,报到n的人出圈,剩下的人继续从1开始报数,直到所有的人都出圈为止。对于给定的m和n,求出所有人的出圈顺序.
  1. import java.util.Scanner;
  2. /**
  3. *使用数组实现约瑟夫环问题
  4. *由m个人围成一个首尾相连的圈报数。
  5. *从第一个人开始,从1开始报数,报到n的人出圈,
  6. *剩下的人继续从1开始报数,直到所有的人都出圈为止。
  7. *对于给定的m和n,求出所有人的出圈顺序.
  8. */
  9. public class RingTest{
  10.     public static void main(String[] args){
  11.         System.out.println("程序说明如下:");
  12.         System.out.println("由m个人围成一个首尾相连的圈报数。从第一个人开始,从1开始报数,报到n的人出圈,剩下的人继续从1开始报数,直到所有的人都出圈为止。对于给定的m和n,求出所有人的出圈顺序.");
  13.         
  14.         //提示输入总人数
  15.         System.out.println("请输入做这个游戏的总人数:");
  16.         Scanner sca=new Scanner(System.in);
  17.         int m=sca.nextInt();
  18.         //提示输入要出圈的数值
  19.         System.out.println("请输入要出圈的数值:");        
  20.         int n=sca.nextInt();
  21.         System.out.println("按出圈的次序输出序号:");        
  22.         //创建有m个值的数组
  23.         int[] a=new int[m];
  24.         //初始长度,以后出圈一个,长度就减一
  25.         int len=m;
  26.         //给数组赋值
  27.         for(int i=0;i<a.length;i++)
  28.             a[i]=i+1;
  29.         //i为元素下表,j代表当前要报的数
  30.         int i=0;
  31.         int j=1;
  32.         while(len>0){
  33.             if(a[i%m]>0){
  34.                 if(j%n==0){//找到要出圈的人,并把圈中人数减一
  35.                     System.out.print(a[i%m]+"  ");
  36.                     a[i%m]=-1;
  37.                     j=1;
  38.                     i++;
  39.                     len--;
  40.                 }else{
  41.                     i++;
  42.                     j++;
  43.                 }
  44.             }else{//遇到空位了,就跳到下一位,但j不加一,也就是这个位置没有报数
  45.                 i++;
  46.             }
  47.         }
  48.     }
  49. }
复制代码


方法2
  1. import java.util.ArrayList;
  2. import java.util.List;

  3. public class Monkey {
  4.         private final static String SVN_VERSION = "$Id$";
  5.         public List sourceList= new ArrayList();//按顺序递增的序列链表,作为源链表,从该链表中移除报了数的成员
  6.         public List finalList= new ArrayList();//最终的结果链表;初始化时链表里全部成员都为零,长度跟源链表一样,每次从源链表中移除一个报数成员,就在该链表中的相同位置增加被移除的序号
  7.         public int k;
  8.         public int n;
  9.        
  10.         /**
  11.          * 初始化源链表和最终的结果链表,原链表中的存放的是整数,按顺序递增;结果链表中存放的全部是零
  12.          * @param k 每报k次数后重新报数
  13.          * @param n 一共有n个人围成一圈报数
  14.          */
  15.         public void init(int k,int n){
  16.                 this.k=k;
  17.                 this.n=n;
  18.                 for(int i=1;i<=n;i++){
  19.                         sourceList.add(i);
  20.                         finalList.add(0);
  21.                 }
  22.                
  23.         }
  24.         /**
  25.          * 排序过程
  26.          */
  27.         public void sequence(){
  28.                 int index =0;//原链表的index,相当于报数指针
  29.                 int seqNum =1;//报数报到K的人,出列顺序
  30.                 System.out.println("链表总长 n="+n+";每次选择k个人报数,K="+k);
  31.                 //只要还有人没报数报到k,就继续循环下去
  32.                 while(!sourceList.isEmpty()){
  33.                         System.out.println("每移除一次报数后的链表内容:");
  34.                         //每次移除一个报到k的人时,从1开始报数,打印这时源链表中的内容
  35.                         for(int a=0;a<sourceList.size();a++){
  36.                                 System.out.println("sourceList["+a+"]="+sourceList.get(a));
  37.                         }
  38.                         //count相当于报数K的计数器,大于k从1开始报数,报到k时移除k,并且跳出该循环
  39.                         for(int count=1;count<=k;count++){
  40.                                 System.out.println("sourceList.size()="+sourceList.size()+";count="+count+";index="+index+";seqNum="+seqNum);
  41.                                 //当总人数只剩下一个人的时候
  42.                                 if(sourceList.size() == 1){
  43.                                         int objInt = (Integer) sourceList.get(0);
  44.                                         System.out.println("END--报数第K个... sourceList[0]="+objInt);
  45.                                         sourceList.remove(0);
  46.                                         finalList.set(objInt-1, seqNum);
  47.                                         break;
  48.                                 }
  49.                                 //当index已经循环到链表最后元素,并且最后一个元素被移除了,index从零算起
  50.                                 if(index == sourceList.size()){
  51.                                         index =0;
  52.                                 }else if(index > sourceList.size())//当index已经循环到链表最后元素可能超过了链表的总长度,index从它多余的元素开始从头算起
  53.                                 {
  54.                                         index =index%(sourceList.size());
  55.                                 }
  56.                                 System.out.println("【index】 =="+index);
  57.                                 //报数还没报到k时,Index增加一,表示报数向下一个元素移动
  58.                                 if(count !=k){
  59.                                         index++;
  60.                                 }else{//报数报到k时,原链表移除该元素,结果链表相应的位置增加被移除的顺序号,并且跳出该循环,从下一个位置开始重新报数
  61.                                         int objInt = (Integer) sourceList.get(index);
  62.                                         System.out.println("@@@报数第K个... sourceList["+index+"]="+objInt);
  63.                                         sourceList.remove(index);
  64.                                         finalList.set(objInt-1, seqNum);
  65.                                         seqNum++;
  66.                                         break;
  67.                                 }
  68.                         }
  69.                 }
  70.                 System.out.println("排序后的链表内容为:");
  71.                 //打印结果链表
  72.                 for(int a=0;a<finalList.size();a++){
  73.                         System.out.println("finalList["+a+"]="+finalList.get(a));
  74.                 }
  75.         }
  76.         /**
  77.          * @param args
  78.          */
  79.         public static void main(String[] args) {
  80.                 // TODO Auto-generated method stub
  81.                 Monkey obj = new Monkey();
  82.                 obj.init(3, 6);
  83.                 obj.sequence();
  84.         }
  85. }
复制代码


方法3:
  1. import java.util.LinkedList;
  2. /**
  3. *
  4. * @author Love yali_deng forever
  5. *
  6. */

  7. public class Yuesefu{

  8.         /**
  9.          * 约瑟夫环是一个数学的应用问题:
  10.          *
  11.          * 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;
  12.          * 他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
  13.          *
  14.          * @param args
  15.          */
  16.         private static StringBuffer removedStr = new StringBuffer("");// 记录删除的数字

  17.         public static void main(String[] args) {
  18.                 long startTime = System.currentTimeMillis(); // 获取开始时间
  19.                 process(5000, 10, 1);
  20.                 System.out.println(removedStr.substring(0, removedStr.length() - 1));
  21.                 long endTime = System.currentTimeMillis(); // 获取结束时间
  22.                 System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
  23.         }

  24.         public static void process(int n, int k, int m) {

  25.                 // 构建一个list,存放人数
  26.                 LinkedList<Integer> list = new LinkedList<Integer>();
  27.                 for (int i = 0; i < n; i++) {
  28.                         if (i + k > n) {
  29.                                 list.add(i + k - n);
  30.                         } else {
  31.                                 list.add(i + k);
  32.                         }
  33.                 }
  34.                 int count = 1;// 记录数的人数
  35.                 cycleCal(list, count, m);
  36.         }
  37.         public static void cycleCal(LinkedList<Integer> list, int count, int m) {
  38.                 int len = list.size();
  39.                 if (len > 1) {
  40.                         for (int i = 0; i < len; i++) {
  41.                                 if (count == m) {// 第m个时,remove
  42.                                         removedStr.append(list.get(i)).append(",");
  43.                                         list.remove(i);
  44.                                         len = list.size();
  45.                                         i--;
  46.                                         count = 0;
  47.                                 }
  48.                                 count++;
  49.                         }
  50.                         cycleCal(list, count, m);
  51.                 } else {
  52.                         if (len != 0) {
  53.                                 removedStr.append(list.get(0)).append(",");
  54.                         }
  55.                 }
  56.         }
  57. }
复制代码

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马