约瑟夫环生者死者游戏(JAVA)

来源:互联网 发布:java程序员面试视频 编辑:程序博客网 时间:2024/04/27 21:04

上周日参加一个比赛,在线编程里面有一道就是约瑟夫环的问题,当时脑子转不过来弯集合用的arraylist重复的元素不进行覆盖导致循环一直跳不出来。。。。尼玛当时看了将近2个点好生郁闷。其实这个解决思路很简单,就是构建一个循环链表的数据结构,然后判断要杀死的人中间的间隔,while不断判断就OK了

内容要求:

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,问他俩站在那两个位置才能活着留下。并打印出死亡位置

构建环形链表的数据结构:

package 约瑟夫环;public class MyLinkedList {    //内部类 place用于包裹链表的节点信息 包含当前位置信息 前一个节点和后一个节点    public class Place{        private String place;        private Place before;        private Place after;        public Place(){        }        public Place(String place,Place before,Place after){            this.place = place;            this.before = before;            this.after = after;        }        public String getPlace() {            return place;        }        public void setPlace(String place) {            this.place = place;        }        public Place getBefore() {            return before;        }        public void setBefore(Place before) {            this.before = before;        }        public Place getAfter() {            return after;        }        public void setAfter(Place after) {            this.after = after;        }    }    public Place header = new Place(null,null,null);    public MyLinkedList(){        header.setBefore(header);        header.setAfter(header);    }    //添加元素的方法    public void add(String value){        Place p = new Place(value,null,null);        p.setAfter(header);        p.setBefore(header.getBefore());        p.getBefore().setAfter(p);        p.getAfter().setBefore(p);    }    //按索引号获得元素    public Place get(int index){        Place result = header;        while(index>0){            if(result.getAfter()!=header){                result = result.getAfter();                index--;            }else{                System.out.println("输入索引超过链表长度或当前链表为空");                System.exit(0);            }        }        return result;    }    //判断元素的长度    public int size(){        int length =0 ;        Place result = header;        while(result.getAfter()!=header){            result = result.getAfter();            length++;        }        return length;    }    //移除当前的节点    public void remove(Place p){        Place before = p.getBefore();        Place after = p.getAfter();        before.setAfter(after);        after.setBefore(before);        p = null;        System.gc();    }}

具体的内容

package 约瑟夫环;import 约瑟夫环.MyLinkedList.Place;public class KillGame {    //引入循环链表    public MyLinkedList mll = new MyLinkedList();    //根据人数初始化链表    public void initList(int number){        for(int i=0;i<number;i++){            mll.add("位置"+(i+1));        }    }    public static void main(String[] args){        KillGame kg = new KillGame();        //初始化了41个人        kg.initList(41);        //计数的标志        int index = 1;        //报数位置 初始的时候指向头        Place p = kg.mll.header;        //开始杀人游戏        while(kg.mll.size()>2){            //假如当前报数位置指向了header节点让其自动移到下一位            if(p == kg.mll.header){                p = p.getAfter();            }            //假如当前计数为报数的第三个人就杀死他            if(index%3==0){                System.out.println(p.getPlace()+"已死亡");                kg.mll.remove(p);                p = p.getAfter();                //否则继续向下进行报数            }else{                p = p.getAfter();            }            //记数号+1            index++;        }        //当前节点为3个时候跳出循环包含两个幸存者和一个header节点        System.out.println();        System.out.println("幸存者所在位置"+kg.mll.get(1).getPlace());        System.out.println("幸存者所在位置"2Bkg.mll.get(2).getPlace());    }}

欢迎讨论

0 0