我在这里要做的是删除每个具有相同深度的元素。所以,例如这个测试
(del-sublist '(a b c (d) ((e) a)) 2)
应该返回:
(A B C (D) (A))
这是我的代码。
(defun del-sublist (l n)
(if (null l) '()
(let ((el (car l)))
(if (= n 0) nil
(cond
((atom el)
(remove nil (cons el
(del-sublist (cdr l) n))))
((listp el)
(remove nil (cons '()
(cons (del-sublist el (- n 1))
(del-sublist (cdr l) n))))))))))
此代码不适用于此类测试:
(del-sublist '(a b c (d (()) e) ((e) a)) 3)
它返回:
(A B C (D E) ((E) A))
当它应该返回时:
(A B C (D () E) ((E) A))
此算法应删除相同深度(或更高)的所有元素,但保留其余部分。我只是不知道如何返回一个空列表。
算法的整个想法是当你进入支架时你的深度水平增加,当你在正确的水平时,你移除那里的所有东西,直到你走出这个支架并且你的深度水平减少回来。
答案 0 :(得分:3)
请注意,在Lisp中()
和NIL
完全相同。
也许是这样的:
(defun del-sublist (l n)
(cond ((null l)
())
((and (atom l) (zerop n))
l)
((zerop n)
nil)
(t
(let ((el (first l)))
(cond ((null el)
(del-sublist (rest l) n))
((atom el)
(cons el (del-sublist (rest l) n)))
(t
(cons (del-sublist el (- n 1))
(del-sublist (rest l) n))))))))
清空清单:
CL-USER 107 > (del-sublist '() 0)
NIL
一个级别:
CL-USER 108 > (del-sublist '(a b c) 0)
NIL
CL-USER 109 > (del-sublist '(a b c) 1)
(A B C)
两个级别:
CL-USER 110 > (del-sublist '(a (b) c) 0)
NIL
CL-USER 111 > (del-sublist '(a (b) c) 1)
(A NIL C)
CL-USER 112 > (del-sublist '(a (b) c) 2)
(A (B) C)
三个级别:
CL-USER 113 > (del-sublist '(a (b (d) e) c) 0)
NIL
CL-USER 114 > (del-sublist '(a (b (d) e) c) 1)
(A NIL C)
CL-USER 115 > (del-sublist '(a (b (d) e) c) 2)
(A (B NIL E) C)
CL-USER 116 > (del-sublist '(a (b (d) e) c) 3)
(A (B (D) E) C)
CL-USER 117 > (del-sublist '(a (b (d) (f) e) c) 3)
(A (B (D) (F) E) C)
CL-USER 118 > (del-sublist '(a (b (d) (f) e) c) 2)
(A (B NIL NIL E) C)
答案 1 :(得分:0)
我认为你应该递归地做这件事。只要n
大于1(或者可能是0?),只需保留每个原子并用(1- n)
递归到每个列表中。当n
为1(或者可能是0?)时,返回空列表。
如果第二个例子没有返回(A B C (D () E) (() A))
,我也看不出你的例子是如何一致的。