Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Lisp:给定级别k上的节点列表_List_Lisp_Common Lisp_Levels - Fatal编程技术网

List Lisp:给定级别k上的节点列表

List Lisp:给定级别k上的节点列表,list,lisp,common-lisp,levels,List,Lisp,Common Lisp,Levels,我想从一棵树上找到所有原子,它们位于给定的能级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 (

我想从一棵树上找到所有原子,它们位于给定的能级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
),而不是不必要地缩写)

变化:

  • 我删除了参数
    pos
    。使用
    k
    简单地倒计时更容易
  • 我将第一个案例改为检查原子(包括
    nil
    )。它返回一个空列表,以便最后一个案例中的
    append
    将放弃它。实际上,返回想要的原子是由第二种情况处理的
  • 我使用了标准的
    remove if
    ,而不是您的
    atoms
    。调用
    补码
    生成一个谓词,该谓词匹配任何非原子的内容。因此,
    remove if
    仅保留原子。您也可以使用
    remove if not
    并省略
    补码,但这是不推荐的
  • 在最后一个例子中,我使用
    (reduce#'append…
    创建原子的平面列表编辑:将其更改为使用
    mapcan

还要注意我是如何在函数的开头放置字符串的。那是一个文档字符串。你应该这样做,而不是像在你的
atoms
中那样在那里添加注释。这样,您就可以使用
(descripe#'findat)
查看文档(或者您可以使用Emacs/IDE查看文档)。

(reduce#'append(mapcar…)
可以缩写为
mapcan
@jkiiski谢谢,它真的帮助了我。
(Complement#'atom)
相同。标准中对
-如果不是
符号的弃用实际上就是弃用。我相信
remove if not
remove if
在野外使用得更多。@Svante关于
consp
的一个好观点,尽管我认为从语义的角度来看,使用
atom
更好,因为它让读者立刻明白你想要原子。我知道很多人使用不推荐的函数,但就我个人而言,我更喜欢尽可能避免使用它们(而且非常方便)。我想这只是一个在整个项目中保持一致性的问题。(1)这是另一个关于“非线性列表”的问题。我知道,但我很少遇到非线性列表:它是老师使用的术语还是教科书?如果你说“树”,我想你的问题会更清楚。(2) 请正确缩进您的代码(3)
defun
清楚地将您的代码标识为
common lisp
,请更新您的标记(4)为什么像在其他问题中一样用粗体写“我的代码”?你将如何学习其他(可能更好的)方法?我使用“非线性”术语,因为我的老师是这么说的。从现在起,我将尝试使用“树”。另外,关于“我的代码”问题,你是对的“。只是有时候,我想先修复我的代码,当然,我愿意接受任何其他不同的解决方案。谢谢您的建议。
(或(atom x)(numberp x))
包含冗余。所有的数字都是原子!
(atom x)
不可能失败,但是
(numberp x)
成功了。是的。。我注意到了,谢谢。
(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)