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

本文通过使用Java中的ArrayDeque和LinkedList数据结构解决约瑟夫环问题,并提供了一个Python版本的实现。对比不同数据结构在解决问题时的性能表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看看我当年拿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>  

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值