约瑟夫(Joeph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
【基本要求】利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号
public class Node {
int data; //用来存放每个人手中的数字
int num; //用来存放每个人的位置
Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
}
public class List {
public static void del(int totalPerson,int[] numbs, int m){
Node head=new Node(); //新建一个头结点
Node cur=head;
Node p=head;
int i;
int k=0;
int[] temps=new int[totalPerson]; //用来存放出列的顺序
for(i=0;i<totalPerson;i++){ //把每个人手持的数字放进链表
Node node=new Node(numbs[i]); //存放第n个人手中的数据的结点
cur.next=node; //cur连接node
cur=node; //cur指向node
cur.num=i+1; //给cur.num赋值
}
cur.next=head.next; //最后一个结点指向头结点的next,头结点不存放数据
while(p.next!=p){ //如果p和p.next没在同一个位置,说明出列还没有完成
for (i = 0; i < m - 1; i++) { //从0开始,p指向想要出列的前一个位置
p = p.next;
}
m = p.next.data; //更新m的值,把要出列的人手里的数据赋给m
temps[k]=p.next.num;
p.next=p.next.next; //断开出列的人
k++;
}
temps[totalPerson-1]=p.num; //链表的最后一个结点
System.out.println("出列的顺序是:");
for(i=0;i<totalPerson;i++){
System.out.print(temps[i]+" ");
}}}
import java.io.*;
public class ListTest {
public static void main(String[] args) throws IOException{
String inputStr;
int totalPerson = 0;
int m=0;
boolean mark=false;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
do {
try {
System.out.println("请输入总游戏人数:");
inputStr = in.readLine();
totalPerson = Integer.parseInt(inputStr);
if (totalPerson <= 0) {
throw new NegativeIntegerException();
}
mark=true;
} catch (NumberFormatException | NegativeIntegerException e) {
System.out.println("非法输入!!!请输入一个正整数!");
}
}while(!mark);
mark=false;
int[] numbs = new int[totalPerson];
do {
try {
System.out.println("请输入每个人手上持有的数字,敲回车隔开:");
for (int i=0;i<totalPerson;i++) {
inputStr = in.readLine();
numbs[i] = Integer.parseInt(inputStr);
if (numbs[i] <= 0) {
throw new NegativeIntegerException();
}
}
mark = true;
} catch (NumberFormatException | NegativeIntegerException e) {
System.out.println("非法输入!!!请输入一个正整数!");
}
}while (!mark);
mark=false;
do {
try {
System.out.println("请输入首次上限值m:");
inputStr = in.readLine();
m = Integer.parseInt(inputStr);
if (m <= 0) {
throw new NegativeIntegerException();
}
mark = true;
} catch (NumberFormatException | NegativeIntegerException e) {
System.out.println("非法输入!!!请输入一个正整数!");
}
}while(!mark);
List.del(totalPerson,numbs,m);
}
private static class NegativeIntegerException extends Throwable {
}
}