Recursion 方案:河内塔楼(递归)
首先,我想说这是家庭作业;所以我不是在寻求解决方案,只是一些建议。我已经沉思了大约一个星期了。我提出的每一个解决方案都不是递归的,因为我无法将列表作为唯一的参数来递归。我的教授说他们可以用大约6个助手函数来完成 如前所述,我必须以列表作为唯一参数来解决这个问题。这是我最近一次尝试的一个例子Recursion 方案:河内塔楼(递归),recursion,scheme,racket,towers-of-hanoi,Recursion,Scheme,Racket,Towers Of Hanoi,首先,我想说这是家庭作业;所以我不是在寻求解决方案,只是一些建议。我已经沉思了大约一个星期了。我提出的每一个解决方案都不是递归的,因为我无法将列表作为唯一的参数来递归。我的教授说他们可以用大约6个助手函数来完成 如前所述,我必须以列表作为唯一参数来解决这个问题。这是我最近一次尝试的一个例子 (define (sumSublists lst) (if (= (length lst) 0) 0 (+ (length (car lst)) (sumSublists (cdr
(define (sumSublists lst)
(if (= (length lst) 0)
0
(+ (length (car lst)) (sumSublists (cdr lst)))
)
)
(define (hanoi towersNum)
(sub1 (sumSublists towersNum))
(if (= (sumSublists towersNum) 1)
(print towersNum)
(begin (if (= (sumSublists towersNum) 1)
(print towersNum)
(hanoi '((car towersNum) (cddr towersNum) (cadr towersNum)))
)
(if (= (sub1 (sumSublists towersNum)) 1)
(print towersNum)
(hanoi '((car towersNum) (cadr towersNum) (cddr towersNum)))
)
(if (= (sub1 (sumSublists towersNum)) 1)
(print towersNum)
(hanoi '((cddr towersNum) (cadr towersNum) (car towersNum)))
)
)
)
)
sumSublists返回游戏中有多少磁盘。我得到了一个无限循环,因为每次使用它时,它都会取相同的值,因此不会减少值。我的问题是,我太习惯于命令式和面向对象的变量使用,所以我不知道当Hanoi只取一个参数时我怎么能做到这一点
<河内代码是我尝试将我的项目从C++变成方案。
感谢您的帮助。顺便说一句,我正在使用Dr.Racket作为我的IDE。河内塔是一个固有的递归问题,它有一个优雅的递归解决方案。我不会直接给出解决方案,但我会解释解决方案背后的直觉。考虑:
+--+||
| 1 | | |
+-----------+ | |
| 2 | | |
+-------------------+ | |
| 3 | | |
+-------------------+ +-------------------+ +-------------------+
A、B、C
给定n
光盘,最小的光盘标记为1
,最大的光盘标记为n
。我们的工作是将所有光盘从堆栈A
移动到堆栈C
,同时保持不变,即较大的光盘可能永远不会放在较小的光盘上。如果没有这个不变量,解决方案将是微不足道的
现在,我们可以将光盘n
从A
移动到C
的唯一方法是首先将其上方的所有光盘从A
移动到B
|||
| | |
| +---+ |
| | 1 | |
+-------------------+ +-----------+ |
| 3 | | 2 | |
+-------------------+ +-------------------+ +-------------------+
A、B、C
我们的解决方案现在很简单。我们可以用三个简单的步骤来解决问题。首先,我们将光盘n
上方的所有光盘从A
移动到B
。接下来,我们将光盘n
从A
移动到C
。最后,我们将剩余的光盘从B
移动到C
将所有光盘从A
移动到C
的问题现在分为两个子问题:
n
的所有光盘从A
移动到B
n
的所有光盘从B
移动到C
A
、B
和C
。但是,我们想从源堆栈、目标堆栈和辅助堆栈的角度来讨论这些堆栈。在解决将光盘n
从A
移动到C
的问题时,我们将A
称为源,将C
称为目标。此外,我们需要使用B
,我们称之为辅助堆栈
需要注意的一件重要事情是源、目标和辅助堆栈不断变化。对于“将光盘n
从A
移动到C
”问题,源是A
,目标是C
。但是,对于“将光盘n-1
从A
移动到B
”问题,源是A
,目标是B
。第三个堆栈(不是源或目标)始终是辅助堆栈
这将给你足够的洞察力来解决河内塔的问题。当你解决这个问题时,你会惊讶地发现,与命令式代码相比,这个解决方案是多么简单、优雅和直截了当。河内塔是一个固有的递归问题,它有一个优雅的递归解决方案。我不会直接给出解决方案,但我会解释解决方案背后的直觉。考虑:
+--+||
| 1 | | |
+-----------+ | |
| 2 | | |
+-------------------+ | |
| 3 | | |
+-------------------+ +-------------------+ +-------------------+
A、B、C
给定n
光盘,最小的光盘标记为1
,最大的光盘标记为n
。我们的工作是将所有光盘从堆栈A
移动到堆栈C
,同时保持不变,即较大的光盘可能永远不会放在较小的光盘上。如果没有这个不变量,解决方案将是微不足道的
现在,我们将光盘n
从A
移动到C
的唯一方法是首先将其上方的所有光盘从A
移动到