-1

我正在尝试实现河内塔。我还没有在递归调用之间打印出任何东西,但我一直收到错误消息

'('(LIST) 'NIL 'NIL) 应该是一个 lambda 表达式

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

(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)))
 )
4

1 回答 1

2

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

(hanoi('('(list)'()'())))

首先,要理解 and 中的引号s 是 'xand'(a b c)形式的简写(quote x)(quote (a b c))(quote anything)就是 get 的语法anything,而anything不是被求值。所以'(1 2 3)给你名单(1 2 3)'1给你1quote只是一个符号,并且可以出现在其他列表中,因此'('(list)'()'())(quote ((quote (list)) (quote ()) (quote ())))评估 list相同((quote (list)) (quote ()) (quote ()))。由于()也可以写成nil(或NIL),所以最后一个与 相同('(list) 'NIL 'NIL)。在 Common Lisp 中,函数调用看起来像

(function arg1 arg2 ...)

其中 eachargi是一种形式,function或者是一个符号(例如 , , list)或一个列表,在这种情况下它必须是一个表达式,例如. 所以,在你的行中hanoicarlambda(lambda (x) (+ x x))

(hanoi('('(list)'()'())))

我们有一个函数调用。 functionhanoi,并且arg1('('(list)'()'()))。但这将如何arg1评估?嗯,它是一个列表,这意味着它是一个函数应用程序。是什么function部分?它是

'('(list)'()'())

这与

'('(list 'NIL 'NIL))

但正如我刚才所说,唯一可以function是的列表是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)))))

我实际上可能会destructuring-bind在这里使用来简化获取a,bcout abc

(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)))))
于 2013-11-11T01:30:40.057 回答