如何将空列表作为列表元素返回

时间:2018-01-05 19:42:13

标签: list recursion lisp common-lisp

我在这里要做的是删除每个具有相同深度的元素。所以,例如这个测试

(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))

此算法应删除相同深度(或更高)的所有元素,但保留其余部分。我只是不知道如何返回一个空列表。

算法的整个想法是当你进入支架时你的深度水平增加,当你在正确的水平时,你移除那里的所有东西,直到你走出这个支架并且你的深度水平减少回来。

2 个答案:

答案 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)),我也看不出你的例子是如何一致的。