在LISP中将点对转换为双元素列表

rcj*_*rcj 2 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)

Jos*_*lor 8

cons单元是一个结构,有两个部分,称为它car和它cdr.该对(1 . 2)是一个缺点细胞,其car1,其cdr2.Lisps中的列表是由cons单元格构建的nil.如何在很多地方描述它的工作原理,包括Lisp中Recursive range的答案增加了一个句号? 列表是空列表()(也称为nil),或者car是列表中第一个元素的cons,它cdr是另一个列表,列表的其余部分.这意味着一个清单

(1 2)
Run Code Online (Sandbox Code Playgroud)

由cons细胞和nilas构成

(cons 1 (cons 2 nil))
Run Code Online (Sandbox Code Playgroud)

如果你已经有了(1 . 2),那么你就可以得到12carcdr.如上所述,你将它们重新组合在一起.那是,

(let ((x '(1 . 2)))
  (cons (car x) (cons (cdr x) nil)))
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用list:

(let ((x '(1 . 2)))
  (list (car x) (cdr x)))
Run Code Online (Sandbox Code Playgroud)

如果你想重复使用相同的利弊电池,可以更换cdr与细胞的(cons 2 nil).例如(并注意我们不再引用该对,因为修改文字数据是未定义的行为):

(let ((x (cons 1 2)))
  (setf (cdr x) (cons (cdr x) nil))
  x)
Run Code Online (Sandbox Code Playgroud)

那也可能是

(let ((x (cons 1 2)))
  (setf (cdr x) (list (cdr x)))
  x)
Run Code Online (Sandbox Code Playgroud)

你也可以使用rplacd:

(let ((x (cons 1 2)))
  (rplacd x (list (cdr x)))
  x)
Run Code Online (Sandbox Code Playgroud)