java实现约瑟夫环
2010-09-03 15:15
357 查看
题目:由n个人围成一个首尾相连的圈报数。
*从第一个人开始,从1开始报数,报到k的人出圈,
*剩下的人继续从1开始报数,直到所有的人都出圈为止。
*对于给定的k和n,求出所有人的出圈顺序.
这段代码是自己写的,辛苦调试了半天,基本思路比较简单,就是做两个List,第一个是用循环遍历源List模拟围成圈子报数的人,每到第k个人就把源List里的这个位置的对象remove掉,并且在结果List中同样的位置加入第几次被移除这个次数,位置是源List里保存的对象。
这里比较难调试的地方是,当源List的长度小于k时,移除源List里的对象后计算下一个index的位置比较麻烦,需要注意循环中优先判断源List的长度只剩一个人的情况,再判断k等于list长度,这是把index置0相当于把指针移到list第一个元素,然后判断k超过list长度,取(k%list的长度)这个余数作为index新坐标,最后再判断当前这个循环式第几个人在报数,不是k就index递增,是k的话就移除当前元素。
*从第一个人开始,从1开始报数,报到k的人出圈,
*剩下的人继续从1开始报数,直到所有的人都出圈为止。
*对于给定的k和n,求出所有人的出圈顺序.
import java.util.ArrayList; import java.util.List; public class Monkey { private final static String SVN_VERSION = "$Id$"; public List sourceList= new ArrayList();//按顺序递增的序列链表,作为源链表,从该链表中移除报了数的成员 public List finalList= new ArrayList();//最终的结果链表;初始化时链表里全部成员都为零,长度跟源链表一样,每次从源链表中移除一个报数成员,就在该链表中的相同位置增加被移除的序号 public int k; public int n; /** * 初始化源链表和最终的结果链表,原链表中的存放的是整数,按顺序递增;结果链表中存放的全部是零 * @param k 每报k次数后重新报数 * @param n 一共有n个人围成一圈报数 */ public void init(int k,int n){ this.k=k; this.n=n; for(int i=1;i<=n;i++){ sourceList.add(i); finalList.add(0); } } /** * 排序过程 */ public void sequence(){ int index =0;//原链表的index,相当于报数指针 int seqNum =1;//报数报到K的人,出列顺序 System.out.println("链表总长 n="+n+";每次选择k个人报数,K="+k); //只要还有人没报数报到k,就继续循环下去 while(!sourceList.isEmpty()){ System.out.println("每移除一次报数后的链表内容:"); //每次移除一个报到k的人时,从1开始报数,打印这时源链表中的内容 for(int a=0;a<sourceList.size();a++){ System.out.println("sourceList["+a+"]="+sourceList.get(a)); } //count相当于报数K的计数器,大于k从1开始报数,报到k时移除k,并且跳出该循环 for(int count=1;count<=k;count++){ System.out.println("sourceList.size()="+sourceList.size()+";count="+count+";index="+index+";seqNum="+seqNum); //当总人数只剩下一个人的时候 if(sourceList.size() == 1){ int objInt = (Integer) sourceList.get(0); System.out.println("END--报数第K个... sourceList[0]="+objInt); sourceList.remove(0); finalList.set(objInt-1, seqNum); break; } //当index已经循环到链表最后元素,并且最后一个元素被移除了,index从零算起 if(index == sourceList.size()){ index =0; }else if(index > sourceList.size())//当index已经循环到链表最后元素可能超过了链表的总长度,index从它多余的元素开始从头算起 { index =index%(sourceList.size()); } System.out.println("【index】 =="+index); //报数还没报到k时,Index增加一,表示报数向下一个元素移动 if(count !=k){ index++; }else{//报数报到k时,原链表移除该元素,结果链表相应的位置增加被移除的顺序号,并且跳出该循环,从下一个位置开始重新报数 int objInt = (Integer) sourceList.get(index); System.out.println("@@@报数第K个... sourceList["+index+"]="+objInt); sourceList.remove(index); finalList.set(objInt-1, seqNum); seqNum++; break; } } } System.out.println("排序后的链表内容为:"); //打印结果链表 for(int a=0;a<finalList.size();a++){ System.out.println("finalList["+a+"]="+finalList.get(a)); } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Monkey obj = new Monkey(); obj.init(3, 6); obj.sequence(); } }
这段代码是自己写的,辛苦调试了半天,基本思路比较简单,就是做两个List,第一个是用循环遍历源List模拟围成圈子报数的人,每到第k个人就把源List里的这个位置的对象remove掉,并且在结果List中同样的位置加入第几次被移除这个次数,位置是源List里保存的对象。
这里比较难调试的地方是,当源List的长度小于k时,移除源List里的对象后计算下一个index的位置比较麻烦,需要注意循环中优先判断源List的长度只剩一个人的情况,再判断k等于list长度,这是把index置0相当于把指针移到list第一个元素,然后判断k超过list长度,取(k%list的长度)这个余数作为index新坐标,最后再判断当前这个循环式第几个人在报数,不是k就index递增,是k的话就移除当前元素。
相关文章推荐
- 约瑟夫环 java实现
- 顺序表实现解约瑟夫环_Java
- Java实现约瑟夫环
- 约瑟夫环java实现的方法
- 约瑟夫环简介,问题以及java实现
- Java语言解决约瑟夫环问题(ArrayList实现)
- 用java实现链表并解决约瑟夫环问题
- 约瑟夫环问题(丢手帕游戏)Java 链表实现
- java链表实现约瑟夫环
- Java实现约瑟夫环
- java用list实现约瑟夫环问题
- 约瑟夫环的java实现
- 约瑟夫环的JAVA实现
- 【约瑟夫环】Java实现:100个人开始从1开始报数,每当报数到3,报数3的人离开,求最后留下来人的位置。
- Java 数组实现约瑟夫环
- Java实现约瑟夫环问题
- 约瑟夫环问题 java代码实现(高效率)
- 用线性表实现约瑟夫环(java版)
- 约瑟夫环的Java实现
- 约瑟夫环的java实现