(pred 'r '(p q r)) -> q
这是我的想法 - - 我已经尝试找到返回特定元素长度的函数,但由于我缺乏语法知识,我无法使用该函数。 - 通过使用length函数作为我的帮助函数,我试图找到列表中元素的前身。
我希望这给你们一些想法,或者如果你们有更好的想法,请告诉我,也请展示编码......
谢谢!
答案 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))))))
请特别注意memv
和pred
之间的相似性。
答案 1 :(得分:0)
您不需要length
函数来执行此操作。
显而易见的经典方法是,如果列表的cadr
等于您想要的元素,则返回列表的car
。否则,返回列表cdr
上的搜索功能。除此之外,您只需处理边界条件(例如,列表为空或仅包含一个项目)。