通过LISP中的嵌套列表递归

时间:2015-01-31 04:52:12

标签: recursion lisp

我在查询第一个元素时试图找到嵌套列表中的其他元素。像这样的东西。 (找到其他' a((a b)(b c)(a d))) - > b和d。到目前为止我已经这样做了:问题是我只得到了b。

(defun findOther (elem L)
       (cond (NIL (null L))
        ((eq elem (caar L)) (cdar L))
        ((findOther elem (cdr L)))))

2 个答案:

答案 0 :(得分:1)

首先对原始代码发表一些评论:

(defun findOther (elem L)
  (cond
    ;; NIL is always false, so you *never* end up using this
    ;; case.  You probably want something like ((null l) '()),
    ;; NULL is still pretty common for this, but since you're
    ;; expecting a list, you could use the slighly more
    ;; descriptive ENDP.
    (NIL (null L))
    ;; When you find an element, you immediately return its
    ;; counterpart, and don't collect it and continue on to
    ;; the rest of the list.  It's also easier to read if
    ;; you use more descriptive names like FIRST and SECOND,
    ;; as in ((eq elem (first (first l))) (second (first l))).
    ;; It's worth noting that unless you have a specific reason
    ;; to use EQ, you might want to use EQL, which is the
    ;; default comparison in most CL functions.
    ((eq elem (caar L)) (cdar L))
    ;; Else, you continue to the rest of the list.  In my
    ;; opinion, REST would be more decriptive than CDR here,
    ;; but recursing and returning the value *is* what you
    ;; want to do here.
    ((findOther elem (cdr L)))))

考虑到其中的一些,我们可以做这样的事情:

(defun others (element list)
  (cond
    ((endp list) '())
    ((eql element (first (first list)))
     (list* (second (first list))
            (others element (rest list))))
    ((others element (rest list)))))

所有这一切,标准库中的功能 会让这更容易。例如。使用 mapcan

(defun others (element list)
  (mapcan (lambda (sublist)
            (when (eql (first sublist) element)
              (rest sublist)))
          list))

(others 'a '((a b) (b c) (a d)))
;=> (B D)

答案 1 :(得分:0)

我不确定您是否正在寻找两个元素的对,或者也可能是列表中的更多元素。万一你有更多的元素,你也想要所有的元素,而且其中一些元素并不是真正的对,

(defun pair-of (elem lis)
 (let ((temp nil))
  (cond
   ((and (listp lis) (not (null lis)))
    (mapcar
     #'(lambda (x)
        (cond
         ((and (listp x) (not (null x)) (eql elem (car x)))
          (push (cdr x) temp))))
     lis)))
  (nreverse temp)))

USAGE:(pair-of 'a '((a b) (b c) (a d w) 1))

输出:((B) (D W))

但是如果你想将它们组合在一个列表中, (reduce #'append (pair-of 'a '((a s) (a 3 8) (2 5 1))):initial-value '()) => (S 3 8)