约瑟夫问题的另类java实现

来源:互联网 发布:爱的算法免费下载 编辑:程序博客网 时间:2024/06/06 08:50

下班到家后,看到CSDN上一篇关于约瑟夫问题的讨论,然后本人的小宇宙也耐不住了,要知道大学时算法问题曾难住过我,于是本人迅速打开eclipse开写,以下是实现部分:

/** * 约瑟夫问题编码解答 */public class JosephusMain {    public static void main(String[] args) {        int m = 120; //总数为m        int k = 67; //第一次从第k个开始数        int n = 28; //每次都要从1到n,第n个数出列        LinkItem first = new LinkItem(1, null);        LinkItem end = initLink(first, m);        end.next = first;        System.out.println("data is ready: " + first.toString() + "&" + end.toString() + "\n");        calculate(getk(first, k), n);    }    /**     * 初始化链表     *     * @param item     * @param count 链表长度     * @return 返回末端链表元素     */    private static LinkItem initLink(LinkItem item, int count) {        if (item.value == count) {            return item;        }        item.next = new LinkItem(item.value + 1, null);        return initLink(item.next, count);    }    /**     * 获取从first开始的第k个值     *     * @param first     * @param k     * @return 返回第k个值     */    private static LinkItem getk(LinkItem first, int k) {        LinkItem itemK = first;        int index = 1;        while (index < k) {            itemK = itemK.next;            index++;        }        return itemK;    }    /**     * 约瑟夫环实现     *     * @param first     * @param n     */    private static void calculate(LinkItem first, int n) {        LinkItem last = getk(first, n - 1);        LinkItem delete = last.next;        System.out.println(delete.toString());        if (last == delete) {            return;        }        last.next = delete.next;        calculate(last.next, n);    }}


链表定义:

public class LinkItem {    public int value;    public LinkItem next;    public LinkItem(int value, LinkItem next) {        this.next = next;        this.value = value;    }    @Override    public String toString() {        return "LinkItem{" +                "value=" + value +                '}';    }}


应用:17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

这个问题的解法是先算出30人的出列顺序,然后在前15个出列的位置上分别站上一个位非教徒,这算是逆向思路求解啦。


0 0
原创粉丝点击