先看看我当年拿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>
好了。。。臣妾可以告退了。。。。