约瑟夫环问题笔试中比较常遇见的一道算法题:
由m个人围成一个首尾相连的圈报数。从第一个人开始,从1开始报数,报到n的人出圈,下一个人继续从1开始报数,直到所有的人都出圈为止。对于给定的m和n,求出所有人的出圈顺序.
下面给出java面向过程的实现方法,读起来可能比较绕,大家参照注释并放到eclipse运行哈应该可以明白:-)
import java.util.Scanner;
public class Josephus {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
System.out.println("程序说明如下:\n");
System.out.println("由m个人围成一个首尾相连的圈报数。\n" + "从第一个人开始,从1开始报数,报到n的人出圈,\n"
+ "剩下的人继续从1开始报数,直到所有的人都出圈为止。\n" + "对于给定的m和n,求出所有人的出圈顺序.\n");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入人数:");
int m = scanner.nextInt();
System.out.println("请输入出局号码:");
int n = scanner.nextInt();
System.out.println("按出圈次序输出序号:");
long s1 = System.currentTimeMillis();
// 创建有m个值得数组,并赋初值
int[] a = new int[m];
for (int i = 0; i < a.length; i++) {
a[i] = i + 1;
}
// 需要出圈的人数
int len = m;
// i为元素下标,j代表当前要报的数
int i = 0;
int j = 1;
while (len > 0) {
if (a[i % m] > 0) {
if (j % n == 0) { // 找到出圈的人,并把圈中人数减一
System.out.print(a[i % m] + " ");
a[i % m] = -1;
j = 1;
i++;
len--;
} else {
i++;
j++;
}
} else { // 遇到空位了,就跳到下一位,但j不加一,也就是这个位置没有报数
i++;
}
}
long s2 = System.currentTimeMillis();
System.out.println("所用总时间为: " + (s2 - s1) + " ms");
}
}