Lisp中的函数参数列表
我有以下代码:Lisp中的函数参数列表,lisp,common-lisp,Lisp,Common Lisp,我有以下代码: (defun TREE-CONTAINS (N TREE) (cond (( = (car TREE) nil) nil) (( = (car TREE) N) t) (t TREE-CONTAINS (N (cdr TREE))) ) ) 它接受一个数字N和一个列表树,并检查列表树中是否存在N。非常简单,但由于某种原因,我在调用函数时不断遇到这个错误 (TREE-CONTAINS 3 '((1 2 3) 7 8)) *** - +:
(defun TREE-CONTAINS (N TREE)
(cond (( = (car TREE) nil) nil)
(( = (car TREE) N) t)
(t TREE-CONTAINS (N (cdr TREE)))
)
)
它接受一个数字N和一个列表树,并检查列表树中是否存在N。非常简单,但由于某种原因,我在调用函数时不断遇到这个错误
(TREE-CONTAINS 3 '((1 2 3) 7 8))
*** - +: (1 2 3) is not a number
代码有问题吗?我对Lisp很陌生,所以也许我只是没有看到一些非常明显的东西。。提前谢谢 语法错误 您的代码包含多个标记为编译器警告的语法错误:
CL-USER> (defun TREE-CONTAINS (N TREE)
(cond (( = (car TREE) nil) nil)
(( = (car TREE) N) t)
(t TREE-CONTAINS (N (cdr TREE)))
)
)
;Compiler warnings :
; In TREE-CONTAINS: Undeclared free variable TREE-CONTAINS
; In TREE-CONTAINS: Undefined function N
TREE-CONTAINS
原因是Common Lisp中的括号与其他编程语言的含义不同:它们不用于指定运算符的应用顺序(如3*(2+4)
,它不同于3*2+4
),而是语法的组成部分,用于指定运算符的不同部分“语句”,如在cond
或在函数应用程序中(如(函数名arg1 arg2…argn)
)。因此,本例中的语法错误出现在最后一行,在最后一行中,您应该调用带有参数N
和(cdr树)
,如下所示:
CL-USER> (defun TREE-CONTAINS (N TREE)
(cond (( = (car TREE) nil) nil)
(( = (car TREE) N) t)
(t (TREE-CONTAINS N (cdr TREE)))
)
)
TREE-CONTAINS
语义错误
但是,如果尝试此功能,您将发现一个错误:
CL-USER> (TREE-CONTAINS 2 '(1 2 3))
The value NIL is not of the expected type NUMBER.
原因是您使用了=
将数字((汽车树)
)与值nil
进行比较,而=
只能用于比较数字。对于一般情况,请使用eq
或eql
:
CL-USER> (defun TREE-CONTAINS (N TREE)
(cond (( eql (car TREE) nil) nil)
(( = (car TREE) N) t)
(t (TREE-CONTAINS N (cdr TREE)))
)
)
TREE-CONTAINS
CL-USER> (TREE-CONTAINS 2 '(1 2 3))
T
还有一个问题:您应该检查列表是否为空,而不是第一个元素是否为零。换句话说,第一个条件应该是:
(cond ((eq TREE nil) nil)
或者更好:
(cond ((null TREE) nil)
文体注释
(defun list-contains (n list)
(cond ((null list) nil)
((= (car list) n) t)
(t (list-contains n (cdr list)))))
检查树而不是列表的成员资格
另一方面,如果你想检查一个通用的树,即一个可以包含子列表的列表,比如在<代码>(树包含3个((1个2个3)7个8))< /C>,在递归中你应该考虑列表中的一个元素本身是一个列表,然后执行双递归。
CL-USER> (list-contains 2 '(1 (2 3) 4))
The value (2 3) is not of the expected type NUMBER.
CL-USER> (defun tree-contains (n tree)
(cond ((null tree) nil)
((listp (car tree)) (or (tree-contains n (car tree))
(tree-contains n (cdr tree))))
((= (car tree) n) t)
(t (tree-contains n (cdr tree)))))
TREE-CONTAINS
CL-USER> (tree-contains 2 '(1 (2 3) 4))
T
除了公认的答案之外,这里还有一种编写相同谓词的替代方法,不使用
cond
:
(defun list-contains-p (number list)
(and (consp list)
(or (= number (first list))
(list-contains-p number (rest list)))))