【问题标题】:'('(LIST) 'NIL 'NIL) should be a lambda expression in (hanoi('('(list)'()'())))'('(LIST) 'NIL 'NIL) 应该是 (hanoi('('(list)'()'()))) 中的 lambda 表达式
【发布时间】:2013-11-11 01:11:37
【问题描述】:

我正在尝试实现Towers of Hanoi。我还没有在我的递归调用之间打印出任何东西,但是我一直收到一个错误提示

'('(LIST) '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)))
 )

【问题讨论】:

    标签: lisp common-lisp towers-of-hanoi


    【解决方案1】:

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

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

    首先,了解'x'(a b c) 中的quotes 是(quote x)(quote (a b c)) 形式的简写,而(quote anything) 是获取anything 的语法,没有@987654330 @被评估。所以'(1 2 3) 给你列表(1 2 3)'1 给你1quote 只是一个符号,并且可以出现在其他列表中,所以 '('(list)'()'())(quote ((quote (list)) (quote ()) (quote ()))) 相同,计算结果为列表 ((quote (list)) (quote ()) (quote ()))。由于() 也可以写成nil(或NIL),所以最后一个与('(list) 'NIL 'NIL) 相同。在 Common Lisp 中,函数调用看起来像

    (function arg1 arg2 ...)
    

    其中每个 argi 是一个表单,function 是一个符号(例如,listhanoicar)或一个列表,在这种情况下,它必须是一个 lambda 表达式,例如,(lambda (x) (+ x x))。所以,在你的行中

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

    我们有一个函数调用。 functionhanoiarg1('('(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 来简化从abc 中获取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)))))
    

    【讨论】:

    • 你好。谢谢!是的,我正在尝试列出一个列表。 (所以一个列表中包含 3 个单独的列表)。另外,如果您阅读我的原始帖子,您会看到我写道,在递归调用之间我什么都没有。我会在那里打印一份声明。
    • @user2974646 好的,但即便如此,对hanoi 的第一次递归调用并没有修改任何内容。在第二次调用中,abc 与第一次递归调用之前完全相同。如果这是你所期望的,很好。我只是想确定一下。
    • 我真的还是卡住了。就像我说的我想要一个列表列表。所以一个列表,其中包含 3 个列表。我希望递归调用替换第一个列表中的所有内容,但列表中的第一项除外(所以我使用了 CDR)。然后我希望第二个列表只将第一个列表中的第一项放入其中,然后我希望第三个列表保持不变。
    • @user2974646 你的意思是hanoi 应该取三个列表的列表?如果abc都是列表,则使用(list a b c)即可。
    • 当我尝试调用 hanoi 函数时,它表示 hanoi 现在需要 4 个参数。我不确定为什么。是因为我有 3 个列表(a b 和 c)以及围绕这 3 个列表的列表吗? (即总共 4 个列表)。
    猜你喜欢
    • 1970-01-01
    • 2012-12-05
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多