【问题标题】:Lisp analyze list of atoms and listsLisp 分析原子列表和列表
【发布时间】:2013-12-06 23:10:50
【问题描述】:
我刚刚学习 lisp,被要求编写一个名为 analyze 的函数,它接受一个列表并返回一个由符号“atom”和“list”组成的列表。
例如,
(analyze ‘(a b (c d) e f)) 应该返回 (atom atom list atom atom)
这是我目前所拥有的:
(defun analyze(l)
(and l
(if (not(null (atom (first l))
)
)
'atom 'list
)
(or (null (rest l))
(analyze (rest l)))
)
)
由于某种原因,它总是返回 T。
【问题讨论】:
标签:
recursion
lisp
iteration
【解决方案1】:
我猜你的意图是这样的:
(defun analyze (l)
(if l ; if list is not empty
(cons ; add
(if (atom (car l)) ; 1) a symbol describing the type of (car a)
'atom
'list)
(analyze (cdr l))))) ; 2) do the same with the rest of the list
正确缩进的代码如下所示:
(defun analyze (l)
(and l
(if (not (null (atom (first l))))
'atom 'list)
(or (null (rest l))
(analyze (rest l)))))
所以它是一个and 之间
- l,列表 - 如果列表不为空,则为 true
- 'atom 或 'list - 都是符号,逻辑上都是真的
- 如果列表的其余部分为空,或者分析结果为真(始终为真),则为真
所以它相当于(和 t t t ...),t 的数量是列表中的项目数。
【解决方案2】:
如果你有一个列表并且想要创建一个具有相同数量元素的新列表,其中新列表的每个元素都是从原始列表中的相应元素以某种方式计算出来的,通常的方法是使用某种映射函数。
这里,mapcar 在 Common Lisp 中是正确的。
atom 和 list 之间的区别并不是真正的二分法——atom 的“对立面”是 cons。练习有两种解释:
-
假设 list 意味着任何不是原子的东西。请注意,nil(与 () 相同,空列表)不是 cons 而是 atom。
(defun type-symbol (thing)
(if (atom thing)
'atom
'list))
-
假设 atom 意味着任何不是列表的东西。在这种情况下,nil 将产生 list。
(defun type-symbol* (thing)
(if (listp thing)
'list
'atom))
将其与mapcar 一起使用:
(defun analyze (list)
(mapcar #'type-symbol list))