Lisp 删除每个子列表的第一个元素
我应该写一个函数来删除每个子列表的第一个元素 所以如果给我们(1(2(34)5)6),我的函数应该返回(((4)5)6) 这是我尝试过的,但它又回来了 ((34)5)6) (3个不应该在那里) 有什么想法吗?你的代码 您的Lisp 删除每个子列表的第一个元素,lisp,common-lisp,Lisp,Common Lisp,我应该写一个函数来删除每个子列表的第一个元素 所以如果给我们(1(2(34)5)6),我的函数应该返回(((4)5)6) 这是我尝试过的,但它又回来了 ((34)5)6) (3个不应该在那里) 有什么想法吗?你的代码 您的podlista函数有4个子句,最后一个子句不可访问。这是因为每个Lisp对象要么是an要么是a,对于acons,都将返回t 下一个问题是第三个子句是非递归的(必须删除cdr中的第一个元素) 但是,您的代码有一个更大的问题。 当函数看到cons时,它必须知道是否要删除第一个元素
podlista
函数有4个子句,最后一个子句不可访问。这是因为每个Lisp对象要么是an要么是a,对于acons
,都将返回t
下一个问题是第三个子句是非递归的(必须删除cdr
中的第一个元素)
但是,您的代码有一个更大的问题。
当函数看到cons
时,它必须知道是否要删除第一个元素。瞧,它一定是
- 使用循环(或映射)以非递归方式处理列表,或者
- 使用第二个参数指定列表中的第一个/非第一个位置
(defun drop-first (l)
(if (consp l)
(mapcar #'drop-first (rest l))
l))
(drop-first '(1 ((7 8) 9) (2 (3 4) 5) 6))
==> ((9) ((4) 5) 6)
(drop-first '(1 (2 (3 4) 5) 6))
==> (((4) 5) 6)
mapcar
当然是递归地定义为
(defun mapcar (f l)
(and l
(cons (funcall f (first l))
(mapcar f (rest l)))))
解决方案2-额外参数
测验
如果你使用标准的缩进和排列,那就太好了。英文函数名也不会有什么坏处。请注意,有些简单的情况下,您的代码无法正常工作,例如
(12)
,它返回NIL
,而不是预期的(2)
。我很想了解我的代码有什么问题,我从未使用过mapcar,也不知道它会做什么。
(defun mapcar (f l)
(and l
(cons (funcall f (first l))
(mapcar f (rest l)))))
(defun first-drop (l &optional (top-level t))
(cond ((atom l) l)
(t
(when top-level ; drop first list element
(pop l))
;; collect all the list element
(cons (first-drop (car l) t) ; drop first in the CAR
(first-drop (cdr l) nil))))) ; do NOT drop first in the rest of the list
(defparameter *test-cases* ; list of (ARG RET)
'(((1 2 3) (2 3))
((1 (2 (3 4) 5) 6) (((4) 5) 6))
((1 (3 (5 6) 4) (7 8 9) 2) (((6) 4) (8 9) 2))))
(loop :for (arg ret) :in *test-cases* :do
(assert (equal (drop-first arg) ret))
(assert (equal (first-drop arg) ret)))