我知道模数给出余数,而这个代码将给出约瑟夫斯问题的幸存者。我注意到一种模式,当n mod k = 0时,起始计数点从圆的最开始开始,当n mod k = 1时,紧接在圆开始之前的那个人幸存下来,执行循环通过圆圈
我只是不明白这个递归如何使用模数来找到最后一个人站立和josephus(n-1,k)实际指的是什么。它是指最后一个被执行的人还是特定回合的最后一个幸存者?
def josephus( n, k):
if n ==1:
return 1
else:
return ((josephus(n-1,k)+k-1) % n)+1
答案 0 :(得分:4)
这个答案既是约瑟夫斯问题的总结,也是对你的问题的回答:
josephus(n-1,k)
指的是什么?当致电josephus(n-1,k)
时,这意味着您已经执行了每个第k个人,总计n-1次。 (改为匹配乔治汤姆林森的评论)
递归一直持续到有一个人站立,当函数返回到顶部时,它将返回你必须存活的位置才能生存。模数运算符用于帮助保持在圈内(正如GuyGreer在评论中所解释的那样)。这是一张有助于解释的图片:
1 2
6 3
5 4
设n = 6且k = 2(在圆圈中执行每第2个人)。首先执行该功能一次,然后执行第二个人,圆圈变为:
1 X
6 3
5 4
继续递归,直到剩下的最后一个人将导致以下序列:
1 2 1 X 1 X 1 X 1 X X X
6 3 -> 6 3 -> 6 3 -> X 3 -> X X -> X X
5 4 5 4 5 X 5 X 5 X 5 X
当我们检查从josephus返回的值时,我们得到以下值:
n = 1 return 1
n = 2 return (1 + 2 - 1) % 2 + 1 = 1
n = 3 return (1 + 2 - 1) % 3 + 1 = 3
n = 4 return (3 + 2 - 1) % 4 + 1 = 1
n = 5 return (1 + 2 - 1) % 5 + 1 = 3
n = 6 return (3 + 2 - 1) % 6 + 1 = 5
这表明约瑟夫(n-1,k)指的是最后一位幸存者的位置。 (1)
如果我们移除了模数运算符,那么你将看到它将返回第11个位置,但这里只有6个,因此模数运算符有助于将计数保持在圆的范围内。 (2)
答案 1 :(得分:2)
您的第一个问题已在上述评论中得到解答。
要回答你的第二个问题,它指的是最后一位幸存者的位置。
考虑j(4,2)。
使用算法给出
j(4,2)=(j(3,2)+1)%4)+1
j(3,2)=(j(2,2)+1)%3)+1
j(2,2)=(j(1,2)+1)%2)+1
j(1,2)=1
等等
j(2,2)=((1+1)%2)+1=1
j(3,2)=((1+1)%3)+1=3
j(4,2)=((3+1)%4)+1=1
现在j(2,2)的表是
1 2
1 x
所以j(2,2)的确是1。
对于j(3,2),我们有
1 2 3
1 x 3
x x 3
所以j(3,2)根据需要是3。
最后,j(4,2)是
1 2 3 4
1 x 3 4
1 x 3 x
1 x x x
告诉我们j(4,2)= 1是必需的。