【问题标题】:Josephus algorithm partial succesJosephus 算法部分成功
【发布时间】:2018-07-23 14:19:19
【问题描述】:

我的朋友告诉我Josephus problem,你有41 的人坐在圈子里。人号1有剑,杀了右边的人,把剑传给下一个人。这种情况一直持续到只剩下一个人活着。我在 python 中提出了这个解决方案:

print('''There are n people in the circle. You give the knife to one of 
       them, he stabs person on the right and
       gives the knife to the next person. What will be the number of whoever
       will be left alive?''')

pplList = []
numOfPeople = int(input('How many people are there in the circle?'))


for i in range(1, (numOfPeople + 1)):
    pplList.append(i)
print(pplList)

while len(pplList) > 1:
    for i in pplList:
        if i % 2 == 0:
            del pplList[::i]
    print(f'The number of person which survived is {pplList[0]+1}')
    break

但它只适用于 42 人。我应该怎么做,或者我应该如何更改代码以使其适用于例如100, 1000 和圈子中的更多人?

我查看了约瑟夫斯问题并看到了不同的解决方案,但我很好奇我的答案在经过一些小的调整后是否正确,或者我应该从头开始。

【问题讨论】:

  • 阅读ericlippert.com/2014/03/05/how-to-debug-small-programs 了解有关如何调试代码的一些提示。
  • 最多只能容纳 42 人是什么意思?当你尝试 43 或更多时会出现什么错误?
  • 那么答案是错误的。我不知道如何写 i % 2 != 0 的条件
  • 如果您单击 Josephus 标签,您将看到带有该标签的所有问题。你会发现许多不同的方法来解决这个问题(以及相关的问题,你不仅想知道谁幸存下来,还想知道受害者的名单按照他们被杀的顺序)。

标签: python algorithm josephus


【解决方案1】:

我看到两个严重的错误。

  1. 我保证del ppList[::i] 所做的事情不会像您希望的那样。
  2. 绕圈时,重要的是要知道您是杀死列表中的最后一个人(列表中的第一个再次杀死)还是没有(列表中的第一个死亡)。

与您断言它最多可以工作 42 个相反,它不适用于许多较小的数字。它不适用于第一个是 2。(它给出 3 作为答案而不是 1。)

【讨论】:

  • 您好,感谢您的回复。 1.是什么意思?应该是 'del pplList[:i]' 还是其他?第一次迭代结束时数字的索引如何变化?我怎么能改变那里的条件?我不知道我说的是否清楚。
  • @piotrulu 导致类似这种奇怪操作的通常过程是,“我正在寻找一种可以在我的脑海中进行神奇操作的语法。”您的回复“应该是……”是该问题的延续。而是描述您的魔术操作,并将其分解为您可以编写的代码。不管你最终需要 1 行还是 10 行,将你的想法分解为更简单的组件。
  • 至于它的实际作用。假设在第二次运行时,您在插槽 2 中看到 3。然后您将从头开始并每隔三个删除一次,因此您从插槽 0、3、6、9、12 中删除人员...(请记住,数组开始在插槽 0。)
  • 如果我可以这样表述的话,恐怕我的 Python 字典中缺少正确的语法。我想多了这个问题,在我的脑海里让它变得不可能,而实际上它可能尽可能简单。你介意给我指出正确的方向吗?例如,如果我选择的带有列表的方法是否适合此任务?还是del pplList[::i] 是您唯一要更改的?编辑:哦,我在你的第二条评论之后发布了
  • @piotrulu 我可以让程序以一百万种方式运行。那不会帮助你。将它分解成小而清晰的碎片。非常非常清楚应该发生什么。放入调试语句以确保这一点,并且只有这样才会发生。重复这个过程,直到你的小而清晰的部分成为 Python 函数。
【解决方案2】:

问题是如果他没有被杀,你最终不会考虑这个人。例如,如果有 9 个人,杀死 8 个后,9 有剑,但你只是从 1 开始,而不是在下一个循环中是 9。正如有人已经提到的那样,它也不适用于较小的数字。实际上,如果您仔细观察,您会在第一个循环中杀死奇数,而不是偶数。这是非常错误的。

您可以按如下方式更正您的代码

while len(pplList )>1:
    if len(pplList )%2 == 0:
        pplList  = pplList [::2] #omitting every second number
    elif len(pplList )%2 ==1:
        last = pplList [-1] #last one won't be killed
        pplList  = pplList [:-2:2]
        pplList .insert(0,last) # adding the last to the start

除了这个方法之外,还有很多非常有效的方法可以解决这个问题。查看this link了解更多信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-18
    • 2017-09-29
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 2019-04-09
    • 2018-01-08
    相关资源
    最近更新 更多