我是 LISP 的新手,我想了解递归。
我所知道的是递归需要一个停止条件。在我下面的代码中,你能向我解释一下为什么 (equal x 0) 1
是我的停止条件,因为 fact(- X 1)
可以像我的第二个条件一样无限期地继续,我已将 t
我的 cond
的第二行设置为 t
,这意味着它应该继续。
但是当我运行该程序时,它运行良好。下面是我的代码(偶然发现的)
(defun fact(x)
(cond
((equal x 0) 1)
(t (*(fact(- x 1)) x))
)
)
最佳答案
cond
表达式有多个子句。每个子句的形式都是 (expr1 expr2)
。如果 expr1
的计算结果为真,则 expr2 被计算,这就是
cond` 的返回值。没有评估其他条款。
因此,一旦 x
变为 0
,cond
的第一个子句的计算结果为 true 并且调用 fact
返回 1
。
cond
的另一个子句的第一个表达式 t
根据定义为真;因此,如果不使用第一个子句,它总是使用第二个子句。 (带有 t
的 cond
子句就像其他语言中“if”语句中的“else”。)
此函数是递归的,如果您使用参数 2 调用它,它会检查 2 == 0,如果不是,则它会用 1 递归调用自身返回的值乘以 2。因为 1 != 0 它将返回 1 的值乘以用 0 递归调用自身的值。由于 0 确实等于 0 它只返回 1,它使用一层返回 1,然后在该递归的顶层使用返回 1 2.
Common Lisp 有一个函数 trace
这会让你看到你的函数何时被调用以及参数是什么。通常每个递归调用都会缩进,因此您可以看到如下内容:
(fact 2)
(fact 1)
(fact 0)
这有助于理解这个函数。
(如评论中所述 - 此函数不捕获负输入的情况 - 但这是错误处理并且可以轻松修复)。
关于lisp - 解释一下我的 LISP 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38483063/