已知题目:
带密码的约瑟夫问题:编号为1,2,......,n的n个人按照顺时针方向围坐一圈,每个人有自己的编号(正整数)、姓名和密码(正整数)三个数据项。一开始任选一个正整数作为报数上限值,从第一个人开始顺时针方向自1开始报数,报到m时停止报数。报m 的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新报数,如此下去,直到所有人全部出队为止。设计一个程序来求出出队顺序。
每个人包含编号,姓名,密码等信息,于是考虑到创建一个类来储存这些信息。
一个动态数组ArrayList用来存放所有人,一个双向环形链表用来模拟报数的场景。
节点类
class MyEntry{//节点类
MyEntry next;
MyEntry last;
int eid;
String value;
int pas;
public MyEntry(int eid, String value, int pas) {
this.eid=eid;
this.value=value;
this.pas=pas;
}
public String toString(){
return eid+","+value+","+pas;
}
}
全局变量
static ArrayList<MyEntry> list;//动态数组
static Scanner input=new Scanner(System.in);
static MyEntry head;//链表头节点
static int flag;//数字m
main函数
public static void main(String[] args) {
int n=input.nextInt();
list=new ArrayList<>();
input.nextLine();//清空键盘缓存区
for(int i=0;i<n;i++){
String[] line=input.nextLine().split(",");
int eid=Integer.parseInt(line[0]);
String value=line[1];
int pas=Integer.parseInt(line[2]);
list.add(new MyEntry(eid,value,pas));
}
flag= input.nextInt();
createNodes(list.size());
}
创建链表
private static void createNodes(int size) {
MyEntry next;
MyEntry last;
head= list.get(0);
last=head;
for(int i=1;i<size;i++){//初始化循环链表
next=list.get(i);
next.last=last;
last.next=next;
last=next;
}
head.last=last;
last.next=head;//头尾相连
play(head);
}
报数
每一次报完数后,动态数组会移除相应的元素,链表也会删除对应的节点
private static void play(MyEntry entry){//遍历链表
int count=1;
MyEntry currentEntry=entry;
while (list.size()>0){
while (count<flag){
currentEntry=currentEntry.next;
count++;
}
if(count==flag){//报数为m
currentEntry.last.next=currentEntry.next;//出列
currentEntry.next.last=currentEntry.last;
list.remove(currentEntry);//动态数组移除该元素
flag=currentEntry.pas;//更新出列m
System.out.println(currentEntry);//输出
currentEntry=currentEntry.next;//从后一位顺时针计数
count=1;//重置计数
}
}
}
完整代码
package test;
import java.util.ArrayList;
import java.util.Scanner;
public class test {
static ArrayList<MyEntry> list;//动态数组
static Scanner input=new Scanner(System.in);
static MyEntry head;//链表头节点
static int flag;//数字m
public static void main(String[] args) {
int n=input.nextInt();
list=new ArrayList<>();
input.nextLine();//清空输入缓存区缓存
for(int i=0;i<n;i++){
String[] line=input.nextLine().split(",");
int eid=Integer.parseInt(line[0]);
String value=line[1];
int pas=Integer.parseInt(line[2]);
list.add(new MyEntry(eid,value,pas));
}
flag= input.nextInt();
createNodes(list.size());
}
private static void createNodes(int size) {
MyEntry next;
MyEntry last;
head= list.get(0);
last=head;
for(int i=1;i<size;i++){//初始化循环链表
next=list.get(i);
next.last=last;
last.next=next;
last=next;
}
head.last=last;
last.next=head;//头尾相连
play(head);
}
private static void play(MyEntry entry){//遍历链表
int count=1;
MyEntry currentEntry=entry;
while (list.size()>0){
while (count<flag){
currentEntry=currentEntry.next;
count++;
}
if(count==flag){//报数为m
currentEntry.last.next=currentEntry.next;//出列
currentEntry.next.last=currentEntry.last;
list.remove(currentEntry);//动态数组移除该元素
flag=currentEntry.pas;//更新出列m
System.out.println(currentEntry);//输出
currentEntry=currentEntry.next;//从后一位顺时针计数
count=1;//重置计数
}
}
}
}
class MyEntry{//节点类
MyEntry next;
MyEntry last;
int eid;
String value;
int pas;
public MyEntry(int eid, String value, int pas) {
this.eid=eid;
this.value=value;
this.pas=pas;
}
public String toString(){
return eid+","+value+","+pas;
}
}
输入数据
5
1,刘三,3
2,李丽,5
3,吴勇,8
4,钱多,2
5,齐民,4
2
输出数据
2,李丽,5
3,吴勇,8
5,齐民,4
4,钱多,2
1,刘三,3
Process finished with exit code 0
以上来自一位初学者的学习经历,希望对你的学习有所帮助。