我想从树上找到所有的原子,它们都位于给定的k级上,我尝试了如下方法:
(defun atoms (l)
;returns the list of atoms of l at its superficial level
(cond
((null l) l)
((or (atom l) (numberp l)) l)
((or (atom (car l)) (numberp (car l)))
(append (list(car l)) (atom (cdr l))))
(T (atoms (Cdr l)))))
(defun findat (l pos k)
(cond
((null l) l)
((= k pos) (atoms l))
((and (or (atom l) (numberp l)) (= k pos)) l)
(T (cons '() (mapcar #'(lambda (l) (findat l (+ pos 1) k)) l)))))
所以,对于样本:l=(a(b(g))(c(d(e))(f)),pos=0,k=2,我应该得到结果:(gdf),但是,我得到了一些错误,说“a不是LIST类型”有人知道如何修复我的代码吗提前谢谢!
最佳答案
这是您的findat
的一个稍微修改的版本您可能需要为函数想出一个更好的名称(至少完整地写出它(find-atoms
),而不是不必要地缩写)。
(defun findat (l k)
"Find atoms on level K in list L."
(cond
((atom l) '())
((= k 0) (remove-if (complement #'atom) l))
(t (mapcan #'(lambda (l)
(findat l (1- k)))
l))))
(findat '(a (b (g)) (c (d (e)) (f))) 2)
; => (G D F)
变化:
我删除了参数
pos
用k
倒计时更容易。我把第一种情况改为检查原子(包括
nil
)它返回一个空列表,以便最后一个案例中的append
将丢弃它实际上,返回想要的原子是由第二种情况处理的。我用的是标准的
remove-if
,而不是你的atoms
对complement
的调用生成一个谓词,该谓词匹配任何非原子的内容因此remove-if
只保留原子您也可以使用remove-if-not
并省略complement
,但这是不推荐的。在上一个例子中,我使用
(reduce #'append ...)
创建原子的平面列表编辑:将其更改为使用mapcan
。还要注意我如何在函数的开头放置一个字符串那是一个文件串您应该这样做,而不是像在
atoms
中那样在那里添加注释这样,您可以使用(describe #'findat)
查看文档(或者使用emacs/ide查看文档)。