我的任务是查找列表中是否包含给定元素(非线性列表)。这就是我现在写的,但是这个函数的返回值是一个列表,我真的不明白为什么。
(setq E 4)
(defun IsMember (L)
(cond
((equal E L)
T
)
((atom L)
NIL
)
(T
(or (mapcar 'IsMember L))
)
)
)
(print (IsMember '(1 2 3 (((4) 5) 6))))
返回值为:(NIL NIL NIL (((T) NIL) NIL))
但如果在给定列表中找不到T
,它应该输出NIL
或E
。
答案 0 :(得分:6)
您的代码:
(defun is-member (l e)
(cond
((equal e l)
t)
((atom l)
nil)
(t
(some #'(lambda (a)
(if (equal t a) t nil))
(mapcar #'(lambda (b) (is-member b e)) l)))))
摆脱IF
你测试某事是否为T然后你返回T.你可以摆脱它。
(defun is-member (l e)
(cond
((equal e l)
t)
((atom l)
nil)
(t
(some #'(lambda (a)
(equal t a))
(mapcar #'(lambda (b) (is-member b e)) l)))))
摆脱EQUAL
由于列表由T和NIL组成,因此也可以替换EQUAL
(defun is-member (l e)
(cond
((equal e l)
t)
((atom l)
nil)
(t
(some #'identity
(mapcar #'(lambda (b) (is-member b e)) l)))))
摆脱MAPCAR
由于MAPCAR返回T和NIL的列表,我们也可以删除它。
结果:
(defun is-member (list e)
(cond ((equal list e) t)
((atom list) nil)
(t (some (lambda (b) (is-member b e))
list))))
摆脱COND条件/值对
由于COND像OR一样使用,我们可以用OR替换COND。我们不再需要拥有条件/值对:
(defun is-member (list e)
(or (equal list e)
(and (consp list)
(some (lambda (b) (is-member b e))
list))))
答案 1 :(得分:2)
您的解决方案可以更简单地重写为:
(defun is-member (element tree)
(flet ((recurse (e) (is-member e tree)))
(or (equal element tree)
(and (consp tree)
(some #'recurse tree)))))
但您甚至不需要使用some
:
(defun is-member (element tree)
(or (equal element tree)
(and (consp tree)
(or (is-member element (car tree))
(is-member element (cdr tree))))))
答案 2 :(得分:0)
感谢您的帮助,设法不再使用OR
(defun IsMember (L E)
(cond
((equal E L)
T
)
((atom L)
NIL
)
(T
(some #'(lambda (A) (if (equal T A) T NIL)
(mapcar #'(lambda (B) (IsMember B E)) L))
)
)
)
不确定是否符合道德规范,但确实有工作......