删除每个子列表的第一个元素

时间:2017-01-11 21:50:36

标签: lisp common-lisp

我应该编写一个函数来删除每个子列表的第一个元素。

所以如果给出(1(2(3 4)5)6),我的函数应该返回(((4)5)6)

(defun izbrisiPrv(lista)
    (cdr lista)
)


(defun podlista(l)
    (cond
        ((null l) nil)
        ((atom (car l)) (podlista(cdr l)))
        ((listp (car l)) (cons (izbrisiPrv(car l)) (cdr l)))
        (t (cons (podlista(car l)) (podlista(cdr l))))
    )
)


(print (podlista '(1 (2 (3 4) 5) 6)))

这是我尝试过但它返回的内容 (((3 4)5)6)

(3不应该在那里)

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您的代码

您的include '../path/to/other_file.php'; echo '<?xml version="1.0" encoding="UTF-8"?>'; ?> 函数有4个cond子句,最后一个子句无法访问。这是因为每个Lisp对象都是atomcons,而listp将为podlista返回t

下一个问题是第三个子句是非递归的(你必须删除cons中的第一个元素。)

但是,您的代码存在更大的问题。 当函数看到cdr时,它必须知道是否要删除第一个元素。 IOW,它必须

  • 有一个循环(或地图)来非递归地处理列表,或
  • 使用第二个参数指定列表中的第一个/非第一个位置

解决方案1 ​​ - 循环/地图

假设你被允许 使用mapcar,解决方案是

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

解决方案2 - 额外参数

(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