选队长的游戏的一个难点在于:如何让指针在到达数组的最后一个位置时,让指针重新回到数组的开头。而解决这个难点的办法是将指针(index)对数组的长度(size)取模。
package chapter2_5;
import java.util.Scanner;
public class Josephus {
private int total; //总人数
private int report; // 要报的数
private int[] group; // 同学们的小组,队列
private int[] out; //出队次序,用数组显示
public Josephus() {
}
public Josephus(int total, int report) {
this.total = total;
this.report = report;
group = new int[total];
for (int i=0; i < group.length; i++) {
group[i]=i;
}
out = new int[total];
}
public void run() {
int counter = 0;
int i = 0; //同学们的小组的数组下标
int j = 0;//出队次序的数组的下标
int outperson = 0; //记录已出环的人数
while(true) {
if (group[i] != -1) { // group[i]的人值如果是-1,代表出环
//如果没有出环,计数器counter加1
counter = counter + 1;
if (counter % report == 0) { //计数器等于要报的数时(就是能被整除的意思)
outperson = outperson + 1; //出环人数加1
group[i] = -1; // 将出队的人的值标记为-1
out[j] = i + 1; //将出队的人的值添加到出队次序里
j = j + 1; //出队的数组的下标加1,为下一个出队的人准备
}
}
i = (i+1) % total; // 如果i到了数组的最后一位,则将i重置为0.(取模来求得余数来把i重新放回到数组开头)
//假设一共有6个人,i=5就是到了数组的最后一个元素,i+1=6,取模6,等于0,回到开头
if (outperson == total) {
//出环人数等于总人数时,意味着所有人都已出队
break;
}
}
//打印出环顺序
System.out.println("出队次序为: ");
for (int k = 0; k < out.length; k++) {
System.out.print(out[k] + " ");
}
}
public static void main(String[] args) {
/**
* 选队长的游戏,1-3报数,报到3号出列,
*/
Scanner input = new Scanner(System.in);
int m = 0;//总的人数
int n = 0;//出队的人要报的数,比如3
while (true) {
System.out.println("请输入总的人数: ");
m = input.nextInt();
System.out.println("请输入要报的数: ");
n = input.nextInt();
if (m!= 0 && n!=0 ) {
Josephus trip = new Josephus (m, n);
trip.run();
break;
}else {
System.out.println("您输入的数据有错误,请重试");
}
}
}
}