【问题标题】:How does python handle tower of hanoi recursion code?python如何处理河内递归代码塔?
【发布时间】:2022-09-27 16:58:03
【问题描述】:
def move_disks(n, from_tower, to_tower, aux_tower):
    result = []
    ###BEGIN SOLUTION
    # base case
    if n == 1:
        return [f\"Move disk {n:} from {from_tower:} to {to_tower:}.\"]
    # recursive case
    else:
        # move n-1 disks from src to an aux tower
        result = move_disks(n-1, from_tower, aux_tower, to_tower)
        # move nth disk src to dest tower
        result += [f\"Move disk {n:} from {from_tower:} to {to_tower:}.\"]
        # move n-1 disks from aux to dest
        result += move_disks(n-1, aux_tower, to_tower, from_tower)
    
    ###END SOLUTION
    return result

#Test cases
result = move_disks(3, \"A\", \"B\", \"C\")
print(result)
assert result == [\"Move disk 1 from A to B.\", \"Move disk 2 from A to C.\", \"Move disk 1 from B to C.\", \"Move disk 3 from A to B.\", \"Move disk 1 from C to A.\", \"Move disk 2 from C to B.\", \"Move disk 1 from A to B.\"]

我的疑问是这个。为什么在 move_disks (在下图中) n=1 时迭代,对于 \"from_tower,to_tower 和 aux_tower\" 分别是 A,B,C。我觉得应该分别是A,C,B。

请参考下面的图片来查看 python 导师可视化。

enter image description here

    标签: python algorithm recursion data-structures


    【解决方案1】:

    为什么在 move_disks(下图中)的 n=1 时迭代,对于“from_tower、to_tower 和 aux_tower”分别是 A、B、C。

    因为整个问题的目标是将整个堆栈从 A 移动到 B。这可以从顶层调用中看出:move_disks(3, "A", "B", "C")。在此调用中,B 是目标。

    现在,当磁盘数量为奇数时,第一次移动(当n==1 时)应该是从 A 到 B(C 是辅助的)。在这个特殊的电话move_disks(3, "A", "B", "C") 中很奇怪。

    请注意,move_disks 的每次执行都有自己的一组名称。你已经明白n在一次执行中的值与另一次执行中的值不同,但同样的原则适用于其他参数:调用者可以将aux_tower作为递归名称to_tower的值传递,等等。

    这是 3 个磁盘过程的第一部分的可视化。每个框都是函数的执行。每个盒子都有自己的一组名称:

    move_disks(3, "A", "B", "C")
    ┌───────────────────────────────────────────────────────────────────┐
    │ locals: n=3, from_tower="A", to_tower="B", aux_tower="C"          │
    │ else-case                                                         │
    │ result = move_disks(2, "A", "C", "B")                             │
    │ ┌───────────────────────────────────────────────────────────────┐ │
    │ │ locals: n=2, from_tower="A", to_tower="C", aux_tower="B"      │ │ 
    │ │ else-case                                                     │ │
    │ │ result = move_disks(1, "A", "B", "C")                         │ │ 
    │ │ ┌───────────────────────────────────────────────────────────┐ │ │
    │ │ │ locals: n=1, from_tower="A", to_tower="B", aux_tower="C"  │ │ │
    │ │ │ if-case                                                   │ │ │
    │ │ │ return ["Move disk 1 from A to B."]                       │ │ │
    │ │ └───────────────────────────────────────────────────────────┘ │ │
    │ │ result += ["Move disk 2 from A to C."]                        │ │
    │ │ result += move_disks(1, "B", "C", "A")                        │ │
    │ │ ┌───────────────────────────────────────────────────────────┐ │ │
    │ │ │ locals: n=1, from_tower="B", to_tower="C", aux_tower="A"  │ │ │
    │ │ │ if-case                                                   │ │ │
    │ │ │ return ["Move disk 1 from B to C."]                       │ │ │
    │ │ └───────────────────────────────────────────────────────────┘ │ │
    │ │ return result                                                 │ │
    │ └───────────────────────────────────────────────────────────────┘ │
    │ ...etc
    

    【讨论】:

    • 感谢您对此进行解释。但我仍然对 python 如何“处理这个”感到困惑
    • 例如,当 n == 2 时,以下是各自的值:from_tower = "A"、to_tower = "C" 和 aux_tower = "B"。 python如何在n == 1中更改这些值,即from_tower =“A”,to_tower =“B”和aux_tower =“C”。
    • 检查递归调用中的参数。它们以不同的顺序给出。喜欢move_disks(n-1, from_tower, aux_tower, to_tower)。这意味着在该递归调用中,变量to_tower 获取调用者的aux_tower,...等的值。这就是交换发生的地方。
    • 请原谅我特里科特。我是 python 和 dsa 的新手。直到交换(n = 2),我才完全理解它。我不明白从 n = 2 到 n = 1 的过程。
    • move_disks 的一次执行的名称是该执行的本地名称,并且与调用者使用的名称不同。只需使用一张纸,然后了解如何通过递归调用传递值,以及接收这些值的名称。
    猜你喜欢
    • 1970-01-01
    • 2014-05-31
    • 2017-02-04
    • 2012-09-11
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    相关资源
    最近更新 更多