lisp - 将点对转换为 LISP 中的双元素列表

标签 lisp common-lisp

我是 lisp 的新手,正在处理一个家庭作业问题以展平嵌套列表。我有我的功能,除了它需要“删除”点对。所以给定 (1 (2 3) (4 . 5) ((6 7) (89))) 我的函数应该输出 (1 2 3 4 5 6 7 8 9)。

所以..我的实际问题..

给定一个点对,例如 (1 . 2),我怎样才能得到列表 '(1 2)

最佳答案

cons cell 是一个由两部分组成的结构,称为 car及其 cdr .这对 (1 . 2)是一个 cons 单元格,其 car1谁的cdr2 . Lisps 中的列表由 cons 单元格和 nil 构建而成.很多地方都描述了这是如何工作的,包括对 Recursive range in Lisp adds a period? 的回答。列表是空列表 () (也称为 nil ),或 car 的缺点是列表的第一个元素,其 cdr是另一个列表,它是列表的其余部分。这意味着一个列表

(1 2)

由 cons 单元和 nil 构成作为

(cons 1 (cons 2 nil))

如果你已经有了 (1 . 2) , 那么你可以得到 12carcdr .你会按照刚才的描述把它们放回去。也就是说,

(let ((x '(1 . 2)))
  (cons (car x) (cons (cdr x) nil)))

或者,您可以只使用 list :

(let ((x '(1 . 2)))
  (list (car x) (cdr x)))

如果你想重复使用相同的 cons 单元格,你可以替换 cdr带有 (cons 2 nil) 的单元格.例如(请注意,我们不再引用该对,因为修改文字数据是未定义的行为):

(let ((x (cons 1 2)))
  (setf (cdr x) (cons (cdr x) nil))
  x)

也可以是

(let ((x (cons 1 2)))
  (setf (cdr x) (list (cdr x)))
  x)

你也可以使用 rplacd :

(let ((x (cons 1 2)))
  (rplacd x (list (cdr x)))
  x)

关于lisp - 将点对转换为 LISP 中的双元素列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21682677/

相关文章:

common-lisp - 可读与 cl-annot (cl-syntax, jonathan) 和 pythonic-string-reader 冲突

lisp - 类终结 : how to avoid creating dummy instances?

macros - 如何在外部宏之前扩展内部宏?

list - 在方案编程方面需要帮助

scheme - (随机)在 biwascheme 方案中

recursion - 优化骑士之旅 LISP

scope - 普通 Lisp : check if lexical variable exists?

lisp - 常见的 lisp 符号匹配

common-lisp - 如何找到所有可用的系统?

lisp - Lisp 代码中长多字符串常量(或变量)的惯用方法