问题
N个人围成一圈,从一开始报数,数到K的人自动退出,然后再从一开始报数。。。依次循环直到所有人都退出
解决方案一-基于list实现
思路:将N个人排号放入list中,数到K的人从list删除,以此类推,直到list .size为零表示所有人全部退出
public static void yueSeFuByList(int peopleNum,int countNum){
if(peopleNum<0 || countNum<=0){//参数校验,人数、计数为负时方法结束
return;
}
List<Integer> list=new ArrayList<Integer>();//新建list,模拟环,并循环将人的编号赋值输入,编号从1开始
for(int i=0;i<peopleNum;i++){
list.add(i+1);
}
int index=0,count=0;//index为0,也就是第一个人开始计数;count记录排除的人数
while(list.size()>0){//list.size()非零,表示还有人没被排除;为0表示所有人均已被排除
index=(index+countNum-1)%list.size();//统计每次数到countNum时的人索引
count++;//排除人数加1
System.out.println("第"+count+"个排除的人是"+list.get(index));
list.remove(index);//排除数到countNum的人
}
}
解决方案一-基于数组实现
思路:将N个人排号放进数组中,数到K的人对应值非0改成0(0表示此人已退出,非0表示未退出),直到未退出的人为0停止循环
public static void yueSeFuByArray(int peopleNum,int countNum){
if(peopleNum<1 || countNum<1){//参数校验,人数、计数为负时方法结束
return;
}
int livePeople=peopleNum,j=0,count=0;//livePeople记录为还留存的人,默认与参与人数一致;j表示数组索引;count报的数值
int []array=new int[peopleNum];//新建数组,并循环将人员编号赋值,1表示人未被排除,0表示人已退出,即不在参与计数
for(int i=0;i<array.length;i++){
array[i]=1;
}
while (livePeople>0){//livePeople非0,表示还有人留存,需全部排除后才结束
if(j==peopleNum){//当索引超过数组界限时,索引归0,即从头继续判断
j=0;
}
if(array[j]==1){//索引对应的人为1,表示人还留存
count++;//报数加1
if(count==countNum){//报的数就是要排除的数,如报到3的人排除
array[j]=0;//该人排除
count=0;//报数器归0,即下次从1开始报
livePeople--;//留存的人减1
System.out.println("第"+(peopleNum-livePeople)+"个排除的是"+(j+1));
}
}
j++;//索引数+1,即下次判断下一个人
}
}
结果验证
验证代码
@Test
public void test4Fun(){
System.out.println("通过list实现");
TestYueye.yueSeFuByList(10,3);
System.out.println("通过数组实现");
TestYueye.yueSeFuByArray(10,3);
}