有人可以在这段代码中解释模数的使用吗?

时间:2014-02-12 19:31:44

标签: algorithm recursion modulus josephus

我知道模数给出余数,而这个代码将给出约瑟夫斯问题的幸存者。我注意到一种模式,当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

2 个答案:

答案 0 :(得分:4)

这个答案既是约瑟夫斯问题的总结,也是对你的问题的回答:

  1. josephus(n-1,k)指的是什么?
  2. 用于什么模数运算符?
  3. 当致电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是必需的。