josephus问题
讲的就是n个人构成一个表,从第k个人开始计数,第m个人退出,并输出其编号,循环执行,直到表为空。注意:计数到表尾时,则从表头继续计数。
#基于list的方法
def josephus_A(n,k,m):
people = list(range(1,n+1))
i = k-1
for num in range(n):
count = 0
while count < m:
if people[i] > 0:
count +=1
if count == m:
print(people[i],end='')
people[i] = 0
i = (i + 1) % n #i是循环索引
if num < n -1:
print(', ',end = '')
else:
print(' ')
return
#基于顺序表的方法,每退出一个人就删除一个元素;这里由于有删除退出人编号的位置
#因此,计数编号和索引编号可以统一
def josephus_B(n,k,m):
people = list(range(1,n+1))
num,i = n,k-1
for num in range(n,0,-1):
i = (i + m -1) % num #既是索引,也是要退出的人员的编号
print(people.pop(i),end = (', ' if num > 1 else '\n')) #删除列表中的对应元素
return
#基于循环表的方法
#Clist循环单链表的代码在上一篇博文中:[https://blog.csdn.net/qq_33375550/article/details/86549303]
class josephus_C(Clist):
def turn(self,m):
for i in range(m):
self.rear_ = self.rear_.next_
def __init__(self,n,k,m):
#构建循环链表
Clist.__init__(self)
for i in range(1,n+1):
self.append(i)
#存储开始计数位置k和第几个人退出m
self.start = k
self.increment = m
def compute(self):
self.turn(self.start-1)
while not self.is_empty():
self.turn(self.increment-1)
print(self.delete_first(),end = '\n' if self.is_empty() else ', ')
#测试
josephus_A(10,2,7)
josephus_B(10,2,7)
s =josephus_C(10,2,7)
s.compute()