Lisp 这篇文章如何为给定列表创建所有子列表的列表?
有人能给我解释一下下面的代码吗? 我理解每一个小部件的功能,但似乎不理解它们是如何协同工作的 函数正在获取一个列表,例如:Lisp 这篇文章如何为给定列表创建所有子列表的列表?,lisp,common-lisp,Lisp,Common Lisp,有人能给我解释一下下面的代码吗? 我理解每一个小部件的功能,但似乎不理解它们是如何协同工作的 函数正在获取一个列表,例如: (1 2 (3 (4 5) (6 7)) 8 (9 10)) 它有5个子列表,并返回所有子列表的列表: ((1 2 (3 (4 5) (6 7)) 8 (9 10)) (3 (4 5) (6 7)) (4 5) (6 7) (9 10)) 代码是: (defun all_sublists (l) (cond ((atom l) nil)
(1 2 (3 (4 5) (6 7)) 8 (9 10))
它有5个子列表,并返回所有子列表的列表:
((1 2 (3 (4 5) (6 7)) 8 (9 10)) (3 (4 5) (6 7)) (4 5) (6 7) (9 10))
代码是:
(defun all_sublists (l)
(cond
((atom l) nil)
(T (apply 'append (list l) (mapcar 'all_sublists l)))
)
)
我知道第一个条件是,如果l是一个原子,返回nil,但是你能解释一下第二个条件是什么吗?为什么我理解的T是真的,你能尽可能简单地解释一下吗?
所有子列表都是一个典型的递归函数。当分析这样的递归函数时,我们可以这样处理:
在查看该函数的实现之前,我们假设它是正确的。那么这个函数是什么呢?我们被告知,它接受一个包含子列表的列表,并返回一个新列表,其中包含原始列表与其所有子列表的连接(递归,因此,如果内部子列表包含其他子列表,则这些子列表将与内部子列表一起返回)。我们假设这是真的,看看函数
第一行很容易理解:对于空列表,即没有元素的列表,既没有原子列表,也没有子列表,我们返回nil
,它实际上就是列表本身,这与函数的定义一致
为了理解第二行,我们从内部表达式开始。那么,什么是(mapcar'all_sublist l)
mapcar
返回一个列表,该列表是通过将某个函数应用于列表的所有元素的结果串联而获得的。在这里,我们将all_子列表
应用于l
的所有元素,因此我们返回一个包含所有此类应用程序结果的列表:换句话说,将all_子列表
应用于l
的每个元素的结果。当一个元素是一个原子时,它返回nil
,而如果一个元素是一个列表,它返回通过将该元素与其所有子列表串联而获得的列表(我们已经知道all_sublist
返回的内容!)。因此,将返回一个包含所有这些结果的列表。现在看一下外部表达式:(apply'附加(列表l)mapcar的结果)
apply
将函数(在本例中为append
)应用于参数列表。因此,在本例中,我们将原始列表l
,mapcar的结果作为唯一元素附加到列表中。因此,我们得到一个由函数递归生成的l
及其所有子列表组成的列表
最后一点:这在某种程度上似乎是“神奇的”,或者可能是“荒谬的”。如果一开始你没有完全理解它,不要气馁。我们都有同样的感觉。但是如果你坚持尝试理解这种递归,你最终会成功的 非常感谢你帮助我理解它