问题描述
我一直在努力压平树结构.我通过将每个原子符号与树中的其余部分进行比较来递归地执行此操作,但是,我的一个朋友建议使用以下代码,我认为它看起来更清晰.我只是不明白这一行:
I was struggling with flattening a tree structure. I was doing it recursively by comparing each atomic symbol to the rest in the tree but, a friend of mine suggested the following code which I think looks cleaner. I just don't understand the line:
((atom tree)(list tree))
我了解他们每个人分别做了什么,我也知道下面的循环需要一个列表或它会导致错误,我怀疑这有很多原因,因为我们将符号转换为列表 if atom返回真.但我仍然觉得我没有完全理解代码.
I understand what each of them do individually, I also know that the loop below takes a list or it causes an error, which I suspect has a lot to due with the reason we're turning the symbol into a list if atom returns true. But I still don't feel like I fully understand the code.
(defun flatten (tree)
(cond ((null tree)
nil
)
((atom tree)(list tree))
(t
(loop for a in tree appending (flatten a)))))
如果有人能抽出时间来解释一下会很棒吗?谢谢!
An explanation would terrific if anyone could spare the time? Thanks!
推荐答案
代码格式相当糟糕.在你问题的第一部分,根本不清楚为什么
The code is rather poorly formatted. In the first part of your question, it's not at all clear why
((atom tree) (list tree))
会出现在任何Common Lisp代码中,因为它看起来像是试图调用(atom tree)
,取回一个函数,然后用(列表树).在上下文中,如果格式正确,则更清晰:
would appear in any Common Lisp code, since it looks like an attempt to call (atom tree)
, get a function back, and call that function with (list tree)
. In context, with proper formatting, it's clearer:
(defun flatten (tree)
(cond
((null tree) nil)
((atom tree)(list tree))
(t (loop for a in tree
appending (flatten a)))))
它是 cond
中的一个子句.它说 if tree
是一个原子(可以是一个符号、一个数字、一个向量等,任何其他不是 cons
),然后返回(list tree)
.正如 larsmans 解释的,flatten
应该总是返回一个列表,这确保了 (例如,flatten 3)
将返回 (3)
.由于 (loop for a in tree ...)
将适用于作为列表的任何 tree
,因此实际上没有必要为 (nulltree)
,因为 nil/()
是 一个列表.这个定义可以简化为:
It's one clause in a cond
. It says that if tree
is an atom (which could be a symbol, a number, a vector, etc., anything else that isn't a cons
), then return (list tree)
. As larsmans explained, flatten
should always return a list, and this ensures that (flatten 3)
, for instance, will return (3)
. Since the (loop for a in tree ...)
will work for any tree
that is a list, there's really no need to have a case for (null tree)
, since nil/()
is a list. This definition could be simplified to:
(defun flatten (tree)
(if (atom tree)
(list tree)
(loop for a in tree
appending (flatten a)))))
Stack Overflow 上有一些类似的问题,有些问题与您发布的内容几乎相同(以格式为模).这位朋友是否根据其中一个提出了建议.无论如何,为了完整起见,您可以看看:
There are some similar questions out there on Stack Overflow, and some have almost identical code to what you posted (modulo the formatting). Did the friend was basing a suggestion on one of those. At any rate, for the sake of completeness, you might have a look at:
- flatten list in lisp
- Flatten Nests Function in Lisp - need help understanding (almost identical code)
- Common Lisp - flatting a list that may contain symbols (similar code)
这篇关于在 Lisp 中展平树结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!