Lisp:返回列表中元素的前导的函数

时间:2014-04-10 00:27:46

标签: lisp

(pred 'r '(p q r)) -> q

这是我的想法 - - 我已经尝试找到返回特定元素长度的函数,但由于我缺乏语法知识,我无法使用该函数。 - 通过使用length函数作为我的帮助函数,我试图找到列表中元素的前身。

我希望这给你们一些想法,或者如果你们有更好的想法,请告诉我,也请展示编码......

谢谢!

2 个答案:

答案 0 :(得分:1)

根据您当前的尝试,这是一个更正版本(带有更正的缩进,作为奖励: - )):

(defun pred (x l)
  (cond ((null (cdr l)) (car l))
        ((eq (cadr l) x) (car l))
        (t (pred x (cdr l)))))

如果找不到预期的元素,您确定要返回列表的最后一个元素吗?看起来......很奇怪,我认为零是一个更好的回报值。


更新:OP希望实现后继功能和前任功能。以下是我在Scheme中实现它们的方法。 (对不起,没有为你做功课,但如果你知道如何将Scheme翻译成Common Lisp,你的生活会更容易。)

(define (succ x lst)
  (cond ((memv x lst) => (lambda (mem)
                           (and (pair? (cdr mem))
                                (cadr mem))))
        (else #f)))

(define (pred x lst)
  (let loop ((prev #f)
             (rest lst))
    (cond ((null? rest) #f)
          ((eqv? (car rest) x) prev)
          (else (loop (car rest) (cdr rest))))))

虽然memv内置于Scheme,但您可以自己非常简单地实现它:

(define (memv x lst)
  (let loop ((rest lst))
    (cond ((null? rest) #f)
          ((eqv? (car rest) x) rest)
          (else (loop (cdr rest))))))

请特别注意memvpred之间的相似性。

答案 1 :(得分:0)

您不需要length函数来执行此操作。

显而易见的经典方法是,如果列表的cadr等于您想要的元素,则返回列表的car。否则,返回列表cdr上的搜索功能。除此之外,您只需处理边界条件(例如,列表为空或仅包含一个项目)。