约瑟夫环带密码问题(双向环形链表+ArrayList)

已知题目

带密码的约瑟夫问题:编号为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

以上来自一位初学者的学习经历,希望对你的学习有所帮助。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值