看到了一个Python解决josephus问题的文章!!10行以内解决~

先看看我当年拿java写的吧……

import java.util.ArrayDeque;
import java.util.LinkedList;

/**********************************************************
 * 
 * 95-772 Data Structures for Application Programmers
 * 
 * Homework 2 Solve Josephus problem with different data structures and compare
 * running time
 * 
 * Andrew id: zqiu (zqiu@andrew.cmu.edu) Name:Zhongtian Qiu
 * 
 **********************************************************/

public class Josephus {
	/**
	 * This method uses ArrayDeque data structure as Queue/Deque to find the
	 * survivor's position.
	 * 
	 * @param size
	 *            Number of people in the circle that is bigger than 0.
	 * @param rotation
	 *            Elimination order in the circle. The value has to be greater
	 *            than 0.
	 * @return The position value of the survivor.
	 */

	public int playWithAD(int size, int rotation) {
		// TODO implement this
		
		// new an arrayqueue and set size
		ArrayDeque<Integer> ad = new ArrayDeque<Integer>(size);
		
		//if the rotation or size number is not available 
		if (rotation <= 0)
			throw new IllegalStateException("rotation should be bigger than zero");
		if (size <= 0)
			throw new IllegalStateException("Exception should be bigger than zero");
		
		//input sequence firstly
		for (int i = 1; i <= size; i++) {
			ad.add(i);
		}
		
		/* there are two conditions: first is that rotation is the multiple of 
		 * the size so that we only remove the last one in the ad; second, under other
		 * conditions, we move the first (rotation%size) from the front to the
		 * back. Then we delete the first one in queue.
		 */
		while (size != 1) {
			if (rotation % size == 0) {
				ad.removeLast();
				size--;
			} else {
				for (int i = 1; i < rotation % size; i++) {
					ad.addLast(ad.removeFirst());
				}
				ad.removeFirst();
				size--;
			}
		}
		return ad.peekFirst();
	}

	/**
	 * This method uses LinkedList data structure as Queue/Deque to find the
	 * survivor's position.
	 * 
	 * @param size
	 *            Number of people in the circle that is bigger than 0.
	 * @param rotation
	 *            Elimination order in the circle. The value has to be greater
	 *            than 0.
	 * @return The position value of the survivor.
	 */
	public int playWithLL(int size, int rotation) {
		// TODO implement this
		
		if (rotation <= 0)
			throw new IllegalStateException("rotation should be bigger than zero");
		if (size <= 0)
			throw new IllegalStateException("Exception should be bigger than zero");
		
		LinkedList<Integer> list = new LinkedList<Integer>();

		for (int i = 1; i <= size; i++) {
			list.add(i);
		}

		/*this method has the similar way of arrayqueue one,
		 * first move front ones to the back, then delete the first one
		 * however, using LinkedList instead of Arrayqueue
		 */
		while (size != 1) {
			if (rotation % size == 0) {
				list.removeLast();
				size--;
			} else {
				for (int i = 1; i < rotation % size; i++) {
					list.addLast(list.removeFirst());
				}
				list.removeFirst();
				size--;
			}
		}
		return list.getFirst();
	}

	/**
	 * This method uses LinkedList data structure to find the survivor's
	 * position. However, this does not use the LinkedList as Queue/Deque.
	 * Instead, this method uses LinkedList as "Linked List."
	 * 
	 * That means, it uses index value to find and remove a person to be
	 * executed in the circle.
	 * 
	 * @param size
	 *            Number of people in the circle that is bigger than 0.
	 * @param rotation
	 *            Elimination order in the circle. The value has to be greater
	 *            than 0.
	 * @return The position value of the survivor.
	 */
	public int playWithLLAt(int size, int rotation) {
		// TODO implement this
		//This is the fastest one because we can find index very quickly
		//But it became slow when rotation is small and rotation is big
		//judge if rotation and size is reasonable
		if (rotation <= 0)
			throw new IllegalStateException("rotation should be bigger than zero");
		if (size <= 0)
			throw new IllegalStateException("Exception should be bigger than zero");
		
		int pointer = 0;//input numbers first
		LinkedList<Integer> listAt = new LinkedList<Integer>();
		for (int i = 1; i <= size; i++) {
			listAt.add(i);
		}
		
		//Every time pointer pointing to the last one by rotating, just delete the last one
		while (size != 1) {
			if ((pointer + rotation) % size == 0) { //when(pointer+rotation) mod size, it's a special condition
				listAt.removeLast();
				pointer = 0;
				size--;
			}

			//otherwise, we delete the mod number of the index in the list
			else {
				listAt.remove((pointer + rotation) % size - 1);
				pointer = (pointer + rotation) % size - 1;
				size--;
			}
		}
		return listAt.getFirst();
	}
}

好了,你可以捏一把汗吧。。。但是python的真实简洁又实惠。。。虽然效率不是很高

def josephus(n,k):  
    link=range(1,n+1)   
    ind=0  
    for loop_i in range(n-1):  
        ind = (ind+k)% len(link)   
        ind-=1  
        print 'Kill:',link[ind]  
        del link[ind]  
        if ind==-1: # the last element of link  
            ind=0  
    print 'survive :',link[0]  
     
  
if __name__ == '__main__':  
  
    josephus(100000,300)  
    print '-'*30  
    josephus(10,5)  
    print '-'*30  
    josephus(10,1)  
然后我就发现了更简单的。。。

def josephus(n,k):  
    link = range(1,n + 1)  
    ind = 0  
    for loop in range(n - 1) :  
        ind = (ind - 1 + k)% len(link)  
        print 'Kill:',link[ind]  
        del link[ind]  
    print 'Survive :',link[0]
但是这个版本只是基于最初版本稍微合并了下对ind的操作

所以后来发现…………

<br>def josephus(n,k):<br>  j = 0<br>   for i in range(2, n + 1):<br>       j = (j + k) % i<br> print j + 1<br>  

好了。。。臣妾可以告退了。。。。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会为您解答。首先,让我们来了解一下约瑟夫问题的背景和规则。 约瑟夫问题一个经典的问题,据说是以色列学者约瑟夫提出的。问题描述如下: 有n个人围成一圈,从第一个人开始报数,报到m的人出圈,剩下的人继续报数,直到只剩下一人。问最后剩下的人是原来的第几个人? 接下来,我们将使用循环链表来解决这个问题。循环链表是一种链表,它的尾结点指向头结点,形成一个环形结构。我们可以通过删除指定节点来模拟出圈的过程。 下面是实现代码: ```python class Node: def __init__(self, data): self.data = data self.next = None class CircularLinkedList: def __init__(self): self.head = None # 添加节点 def append(self, data): new_node = Node(data) if not self.head: self.head = new_node new_node.next = self.head else: current = self.head while current.next != self.head: current = current.next current.next = new_node new_node.next = self.head # 删除节点 def remove(self, node): if not self.head: return if self.head == node: current = self.head while current.next != self.head: current = current.next current.next = self.head.next self.head = self.head.next else: current = self.head prev = None while current.next != self.head: prev = current current = current.next if current == node: prev.next = current.next break # 获取链表长度 def get_length(self): if not self.head: return 0 current = self.head count = 1 while current.next != self.head: count += 1 current = current.next return count # 解决约瑟夫问题 def josephus(self, step): current = self.head while self.get_length() > 1: count = 1 while count != step: current = current.next count += 1 print("出圈的人是:", current.data) self.remove(current) current = current.next print("最后剩下的人是:", self.head.data) if __name__ == '__main__': cll = CircularLinkedList() n = int(input("请输入总人数: ")) m = int(input("请输入报数的大小: ")) for i in range(1, n+1): cll.append(i) cll.josephus(m) ``` 在这个程序中,我们定义了Node类和CircularLinkedList类。Node类表示一个节点,它包含一个数据域和一个指向下一个节点的指针。CircularLinkedList类表示一个循环链表,它包含一个头结点和一些操作方法。 在主程序中,我们首先创建一个CircularLinkedList对象,然后输入总人数和报数的大小,利用循环将每个人添加到链表中。最后,我们调用josephus方法解决约瑟夫问题,输出出圈的人和最后剩下的人。 希望这个程序能够帮助您解决约瑟夫问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值