【发布时间】:2018-10-28 17:35:19
【问题描述】:
我试图通过创建一个函数来更好地理解 lisp 中的多级列表,在该函数中,我从多级列表中删除所有不是数字的元素。我首先尝试使用 sriv0 函数将其展平,然后检查列表的第一个参数是否为数字。但是我在尝试该功能时遇到问题
(func '(5 (5 2 (8)(7 (9)5))))
.我得到 :COND :variable IF HAS NO VALUE
代码:
(DEFUN striv0 (lis)
(COND ((NULL lis) NIL)
((ATOM lis) (LIST lis))
(T (APPEND (striv0 (FIRST lis))
(striv0 (REST lis))))
))
(DEFUN func (lis)
(LET( (newList (striv0 lis)) ))
(COND ((NULL newList) NIL)
( T(IF (NUMBERP (FIRST newList))
((func(REST newList)))))))
我相信我已经设法解决了这个问题,方法是通过检查数字参数或内部列表来将第二个函数融入第一个函数,如果两者都不是,它会沿着列表进一步移动。:
(DEFUN checkNumber (lis)
(COND ((NULL lis) NIL)
((ATOM lis) (LIST lis))
(T (if ( or(NUMBERP ( FIRST lis))(LISTP (FIRST lis)))
(APPEND ( checkNumber (FIRST lis))
( checkNumber (REST lis)))
( checkNumber (REST lis)) )
)
)
)
【问题讨论】:
-
第二个函数中的
COND语法错误。(cond ... (if ...))应该是(cond ... (t (if ...)))就像上面的其他函数一样。此外,您正在调用STRIV0,但您没有对返回值做任何事情,因此它实际上并没有完成任何事情(STRIV0没有修改参数,它返回一个新列表)。跨度> -
我已经修改了代码。但是现在我得到了 "program stack overflow.RESET" 。我跟踪了这个函数,我可以看到在展平列表之后它没有做任何事情(除了它在崩溃之前写入 func'(5 5 2 8 7 9 5) 多达数千个。
-
还有一些问题。首先,您应该使用
LET来定义局部变量,而不仅仅是SETF定义一个不存在的变量。堆栈溢出是由一次又一次地用整个列表调用FUNC引起的。您应该改为在列表的REST上调用它。此外,(append (first newList) ...)不起作用,因为NEWLIST的FIRST是一个数字,但APPEND需要列表。您应该改用CONS。对(append nil ...)的调用也是不必要的,因为将列表附加到NIL(一个空列表)总是会产生相同的列表。 -
我已经修改了,但是在 lisp 中是否接受离开没有 else 子句的 IF 语句?另外,当我在 REST newList 上应用 func 时,它应该重做所有步骤,这是否意味着在进行展平时它会因为没有嵌套列表而溢出?
-
以可读的方式格式化程序代码很重要。不幸的是,您发布的内容无法阅读。尝试改进缩进和格式。这与任何其他编程语言没有什么不同——因为 Lisp 是作为嵌套列表编写的,所以缩进和格式化程序相对容易。您需要查看代码中列表的开始位置和结束位置。
标签: lisp common-lisp