选队长的游戏的一个难点在于:如何让指针在到达数组的最后一个位置时,让指针重新回到数组的开头。而解决这个难点的办法是将指针(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加1counter = counter + 1;if (counter % report == 0) { //计数器等于要报的数时(就是能被整除的意思)outperson = outperson + 1; //出环人数加1group[i] = -1; // 将出队的人的值标记为-1out[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;//出队的人要报的数,比如3while (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("您输入的数据有错误,请重试");}}}}
