gpt4 book ai didi

recursion - 返回 Lisp 中递归函数的顶层调用

转载 作者:太空宇宙 更新时间:2023-11-03 18:36:27 25 4
gpt4 key购买 nike

我有一个递归函数,它需要递归直到找到某个结果。然而,在我第一次递归调用后的函数体中,我可能会做一些其他计算或者可能再次递归。但是,如果我递归并找到我正在寻找的结果,那么我想停止我一直在做的任何递归并返回该结果以避免进行不必要的计算。

在正常的递归调用中,一旦到达“基本情况”,该情况将返回给调用的函数,然后返回给调用它的函数,依此类推。我想知道如何只返回到第一次调用该函数时,而不必为所有这些中间步骤返回一些东西。

对于我的基本递归,我可以编写如下函数:

(defun recurse (x)
(if (= x 10)
(return-from recurse x)
(progn (recurse (+ x 1)) (print "Recursed!")))))
(recurse 1)

它的编写是为了说明我所说的函数在递归调用后运行更多计算的意思。而且,正如所写,这甚至没有返回我感兴趣的值,因为我在返回我关心的值后进行了一些打印。 (注意:return-from 命令在这里是无关紧要的,因为我可以在它的位置写上“x”。它只是为了在下面的第二个示例中尝试返回顶级递归时画出相似之处。)

现在,如果我想放弃所有那些额外的“递归!”我可以将所有内容都封装在一个 block 中,然后返回到该 block :

编辑:这是我的原始示例的函数包装器。这个例子现在应该更清楚了。

(defun recurse-to-top (start)
(block top-level
(labels ((recurse (x)
(if (= x 10)
(return-from top-level x)
(progn (recurse (+ x 1)) (print "Recursed!")))))
(recurse start))))

然后继续运行这个 block ,直到“找到”10,然后从顶级 block 返回,没有多余的打印,就像我想要的那样。但是,这似乎是获得此功能的一种非常笨拙的方法。我想知道是否存在获得此类行为的标准或“最佳”方法。

最佳答案

DEFUN 已经设置了一个词法 block :

(defun recurse (start)
(labels ((recurse-aux (x)
(case x
(10 (return-from recurse x))
(15 x)
(otherwise
(recurse-aux (+ x 1))
(print "Recursed!")))))
(recurse-aux start)))

较早的是使用 CATCHTHROW,这是一个更动态的结构,因此允许跨函数退出:

(defun recurse (start)
(catch 'recurse-exit
(recurse-aux start)))

(defun recurse-aux (x)
(case x
(10 (throw 'recurse-exit x))
(15 x)
(otherwise
(recurse-aux (+ x 1))
(print "Recursed!")))))
(recurse-aux start))))

正如 Lars 所提到的,还有更多的方法可以像这样对控制流进行编程。

关于recursion - 返回 Lisp 中递归函数的顶层调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26291864/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com