【问题标题】:Towers of Hanoi recursion in python, understanding the change in disc destination [duplicate]python中的汉诺塔递归,了解磁盘目的地的变化[重复]
【发布时间】:2014-04-25 20:31:32
【问题描述】:

我正在努力提高我对python中河内塔递归解决方案代码的理解。

这段代码:

def moveTower(height,fromPole, toPole, withPole):
    if height >= 1:
        print( "    "*(3-height), "moveTower:", height, fromPole, toPole )
        moveTower(height-1,fromPole,withPole,toPole)
        moveDisk(fromPole,toPole,height)
        moveTower(height-1,withPole,toPole,fromPole)
    #print(withPole)

def moveDisk(fp,tp,height):
    print("    "*(4-height), "moving disk", "~"*(height), "from",fp,"to",tp)


moveTower(3,"A","B","C")

将打印解决难题所需的正确动作,所以我前一段时间在堆栈溢出时询问了它是如何做到的。我得到了这个答案

moveTower: 3 A B
     moveTower: 2 A C
         moveTower: 1 A B
             moving disk ~ from A to B
         moving disk ~~ from A to C
         moveTower: 1 B C
             moving disk ~ from B to C
     moving disk ~~~ from A to B
     moveTower: 2 C B
         moveTower: 1 C A
             moving disk ~ from C to A
         moving disk ~~ from C to B
         moveTower: 1 A B
             moving disk ~ from A to B

关于这个解释,我唯一不明白的是,在递归中,光盘目标(peg a、b、c)如何变化?第 3 行 - moveTower: 1 A B,是正确的,我知道光盘应该从 A 移动到 B,但我不明白我们如何从 A 到 C(第 2 行)到新的目的地 B!这很难解释,如果您不明白我的意思,请询问,但我真的希望能帮助您理解这一点!

这就是我理解的 3 张光盘从 =A、to=B、with=C 的代码样子,我已经写了我认为递归的样子(这忽略了大部分代码,我只关注顶部

def moveTower(3,A, B, C):
    if height >= 1:

        moveTower(2,A,C,B)
            moveTower(1,A, C, B) #so this line of code should be A,B,C but why? as in recursion do we not simply repeat the code again and again? so why would it change if the code initially is ACB why does it change to ABC? 
            moveDisk(A,B,3)
            moveTower(1,C,B,A)

【问题讨论】:

  • 仔细查看fromPoletoPolewithPole
  • 嗨@Jasper 肯定在递归中,fromePole toPole withPole: moveTower(height-1,fromPole,withPole,toPole) 的排列保持不变?因此我不明白它是如何变化的?
  • 它确实保持不变!函数参数为from, to, with,第一次递归调用为from, with, to,第二次为with to from
  • 你的问题真的是“如何”或“为什么”改变钉子(以及按什么顺序)?
  • 你明白参数传递给方法的顺序很重要吗? divide(x, y)divide(y, x) 不同。当您将相同的参数传递给函数时,您以不同的顺序传递它们,即参数具有不同的“角色”,以这种方式调用它。一个电话中的from_pole 是另一个电话中的with_pole

标签: python recursion towers-of-hanoi


【解决方案1】:

不要混淆程序中编写的代码和执行的代码,尤其是变量名!

def moveTower(3, A, B, C):
    if height >= 1:

        moveTower(2,A,C,B)
            moveTower(1,A, C, B) #so this line of code should be A,B,C but why? as in recursion do we not simply repeat the code again and again? so why would it change if the code initially is ACB why does it change to ABC? 
            moveDisk(A,B,3)
            moveTower(1,C,B,A)

从正确的代码中考虑这个具有较短变量名的 sn-p:

def moveTower(height, a, b, c):
    if height >= 1:
        moveTower(height-1, a, c, b)

如果第一个调用是moveTower(3, 'Peg1', 'Peg2, 'Peg3'),这意味着必须将 3 个磁盘(整个塔)从 peg 1 移动到 peg 2,同时使用 peg 3 作为临时存储。现在在函数moveTower 中,变量a 得到'Peg1'b 得到'Peg2'c 得到'Peg3'

现在递归开始:要将 3 个磁盘从 peg 1 移动到 peg 2,首先将两个磁盘移动到“helper peg”,然后使用第三个 peg 作为新的助手:

moveTower(2, a, c, b) # in the first call, a=Peg1, b=Peg2, c=Peg3

这导致再次调用moveTower,但这一次,我们有:a 得到'Peg1'b 得到'Peg3'c 得到'Peg2'因为@987654339 @ 和 b 在调用中交换。然后又进行了一步递归:

moveTower(1, a, c, b) 

变量名相同,但现在它们的值不同:c'Peg2'!所以在moveTower 的下一个实例中,我们有(与第一次调用相同):a 得到'Peg1'b 得到'Peg2' 因为它是第二个参数,并且在调用moveTower,第二个参数是c='Peg2'newc从前b得到'Peg3'

我希望这会有所帮助。如果您手动进行递归(使用笔和纸)并写下每个步骤中哪个变量具有哪些内容,您可能也会更好地理解它。

【讨论】:

    猜你喜欢
    • 2017-06-30
    • 2013-08-31
    • 1970-01-01
    • 2014-05-31
    • 2021-07-06
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多