Lisp “('(LIST)'NIL'NIL)应该是(hanoi('('(LIST)()))中的lambda表达式

Lisp “('(LIST)'NIL'NIL)应该是(hanoi('('(LIST)()))中的lambda表达式,lisp,common-lisp,towers-of-hanoi,Lisp,Common Lisp,Towers Of Hanoi,我正在尝试实现。我还没有打印出递归调用之间的任何内容,但我一直收到一个错误,即 列表“NIL”NIL应该是lambda表达式 我已经读到发生这种情况的原因是因为括号有问题,但是我似乎找不到我的问题是什么。当我试图调用hanoi函数时,我认为它发生在pass list函数中。我的代码: (defun pass-list(list) (hanoi('('(list)'()'()))) ) (defun hanoi ('('(1) '(2) '(3))) (hanoi '('(cdr

我正在尝试实现。我还没有打印出递归调用之间的任何内容,但我一直收到一个错误,即

列表“NIL”NIL应该是lambda表达式

我已经读到发生这种情况的原因是因为括号有问题,但是我似乎找不到我的问题是什么。当我试图调用hanoi函数时,我认为它发生在pass list函数中。我的代码:

(defun pass-list(list)
   (hanoi('('(list)'()'())))
)

(defun hanoi ('('(1) '(2) '(3)))

    (hanoi '('(cdr 1) '(cons(car 1) 2) '(3)))

    (hanoi '('(cons(car 3)1) '(2)'(cdr 3)))
 )

这段代码有很多语法问题;到处都有错误的引号,看起来你试图用数字作为变量,这是行不通的。您提到的特定错误消息的来源是

(hanoi('('(list)'()'())))
首先,要理解'x'和'abc'中的s是quote x和quote abc形式的简写,quote anything是获取任何内容的语法,不需要计算任何内容。所以'123'给你列表1231给你1。引号只是一个符号,可以出现在其他列表中,所以列表与报价列表相同,其计算结果与列表报价相同。由于也可以写为nil或nil,最后一个与'list'nil'nil相同。在Common Lisp中,函数调用如下所示

(function arg1 arg2 ...)
其中,每个argi是一种形式,函数是一个符号,例如list、hanoi、car或list,在这种情况下,它必须是lambda表达式,例如lambda x+x。那么,在你的队伍里

(hanoi('('(list)'()'())))
我们有一个函数调用。函数是hanoi,arg1是list。但是如何评估这个arg1呢?它是一个列表,这意味着它是一个函数应用程序。功能部分是什么?它是

'('(list)'()'())
这和

'('(list 'NIL 'NIL))
但正如我刚才所说的,唯一可以作为函数的列表是lambda表达式。这显然不是一个lambda表达式,因此您得到了所看到的错误

我不能确定,但看起来你的目标是如下。标记为**的行有点问题,因为您正在使用一些参数调用hanoi,如果返回,它将在何时返回;在我看来,在这种情况下,你将永远递归,你不会对结果做任何事情。忽略它,然后进入第三行

(defun pass-list(list)
  (hanoi (list list) '() '()))

(defun hanoi (a b c)
  (hanoi (rest a) (cons (first a) b) c)  ; **
  (hanoi (cons (first c) a) b (rest c)))
如果hanoi应该把一个列表作为一个参数,而这个列表应该包含三个列表,我不知道为什么你会这样做,而不是让hanoi只接受三个参数,但这是一个不同的问题,我想,修改很容易;只需获取一个参数abc并从中提取第一个、第二个和第三个列表,然后在递归调用中将单个列表传递给hanoi:

(defun hanoi (abc)
  (let ((a (first abc))
        (b (second abc))
        (c (third abc)))
    (hanoi (list (rest a) (cons (first a) b) c))
    (hanoi (list (cons (first c) a) b (rest c)))))
实际上,我可能会用这里来简化从abc中获取a、b和c的过程:


你好。非常感谢。是的,我试着做一个清单,一个清单。因此,一个列表中包含3个单独的列表。另外,如果你读了我的原始文章,你会发现我写的递归调用之间什么都没有。我将在那里放一个print语句。@user2974646 OK,但即便如此,对hanoi的第一个递归调用并没有修改任何内容。在第二个调用中,a、b和c与第一个递归调用之前完全相同。如果这是你所期望的,那很好。我只是想确定一下,我真的还是被卡住了。就像我说的,我想要一份清单。一个列表,里面有三个列表。我希望递归调用替换第一个列表中的所有内容,但列表中的第一项除外,因此我使用了CDR。然后,我希望第二个列表只包含第一个列表中的第一项,然后我希望第三个列表保持不变。@user2974646您的意思是河内应该包含三个列表?如果a、b和c都是列表,只需使用列表a、b和c。当我尝试调用hanoi函数时,它表示hanoi现在需要4个参数。我不知道为什么。是不是因为我有三个列表a、b和c,以及围绕这三个列表的列表?i、 e.4列出总数。
(defun hanoi (abc)
  (destructuring-bind (a b c) abc
    (hanoi (list (rest a) (cons (first a) b) c))
    (hanoi (list (cons (first c) a) b (rest c)))))