【问题标题】:Lisp association list errorLisp 关联列表错误
【发布时间】:2016-04-06 16:32:20
【问题描述】:

我编写了将 cons 单元格插入关联列表的代码。 比如有关联列表

((1 . a) (3 . c) (4 . d))

我想插入 cons 单元格(2 . b) 然后这个程序产生

((1  a) (2 . b) (3 . c) (4 . d))

但我的代码引发了异常

(car L) should be a lambda expression

下面是我的代码

(defun INSERTCELL (R L)
  (cond ((< (car L) (car R)) cons((car L) INSERTCELL(R (cdr L))))
        (t cons(R L))))

R(2 . b)L((1 . a) (3 . c) (4 . d)),所以R 应该插入L

【问题讨论】:

  • 函数被称为(cons args...) 而不是cons(args...)

标签: lisp


【解决方案1】:

SDS's answer 会处理您代码中的印刷问题以及其他一些错误。也就是说,我认为值得注意的是,可能还有其他方法可以做到这一点。首先,关联列表不必按顺序存储。如果您不需要按顺序排列,则只需使用acons 将新元素添加到开头即可:

(let ((alist '((1 . a) (3 . c) (4 . d))))
  (acons 2 'b alist))
;=> ((2 . B) (1 . A) (3 . C) (4 . D))

如果确实需要维护排序条件,一种选择是使用上述方法,然后sort 列表。不过,这可能有点矫枉过正,因为您已经知道关联列表已排序,您只需将新元素放在其位置即可。为此,您可以使用内置的merge 函数来合并您的关联列表和新元素(通过将其包装在一个列表中,因此它是一个元素的关联列表):

(let ((alist (copy-list '((1 . a) (3 . c) (4 . d))))
      (new (list (cons 2 'b))))
  (merge 'list alist new '< :key 'car))
;=> ((1 . A) (2 . B) (3 . C) (4 . D))

(let ((alist '((1 . a) (3 . c) (4 . d))))
  (merge 'list (copy-list alist) (copy-list '((2 . b)))
         '< :key 'car))
;=> ((1 . A) (2 . B) (3 . C) (4 . D))

请注意,合并是破坏性的(即允许修改其参数),这就是我在这里使用 copy-list 来获取新数据的原因。在您的情况下,由于您可能正在逐步建立列表,所以可能没问题,只要您保存结果。例如,

(defun insert-cell (key value alist)
  (merge 'list alist (list (cons key value))
         '< :key 'car))
(let ((alist '()))
  (setf alist (insert-cell 1 'a alist))
  (setf alist (insert-cell 4 'd alist))
  (setf alist (insert-cell 3 'c alist))
  (setf alist (insert-cell 2 'b alist))
  alist)
;=> ((1 . A) (2 . B) (3 . C) (4 . D))

【讨论】:

    【解决方案2】:

    Lisp 中的函数调用是 cons cells:

    (cons 1 2)
    ==> (1 . 2)
    

    如果你修复你的代码:

    (defun insertcell (R L)
      (cond ((< (caar L) (car R)) (cons (car L) (insertcell R (cdr L))))
            (t (cons R L))))
    

    有效:

    (insertcell '(2 . b) '((1 . a) (3 . c) (4 . d)))
    ==> ((1 . A) (2 . B) (3 . C) (4 . D))
    

    请注意,您还需要使用(caar L),而不是(car L),因为L 是一个alist,因此要访问第一个密钥,您需要调用car 两次。

    【讨论】:

    • 我认为操作会受益于指出它们可以理解地滑入 func(arg1 arg2) 语法三个(至少)位置。见鬼,如果我有足够的 JS,我什至可以做到。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多