【问题标题】:Converting a dotted pair to a two-element list in LISP在 LISP 中将点对转换为二元素列表
【发布时间】:2014-02-10 16:31:05
【问题描述】:

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

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

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

【问题讨论】:

  • 您可能想试验一下函数 CONS 和 LIST。还有一些其他有用的功能。你的演讲应该得到一些指导。到目前为止,您尝试过什么?
  • 另外,如果您搜索[lisp] flatten,您会在此处找到许多相关问题和答案。您或许可以在其中找到您要寻找的内容。
  • 显然使用 car 和 cdr 非常简单。相对于我学过的所有其他语言,lisp 上的文档如此之少让我感到惊讶。
  • @rcj 实际上有很多;规范的超文本版本(HyperSpec)非常好。对于这种情况,您应该专门查看car and cdr accessors,更一般地查看章节14. Conses
  • 我想当我说文档时,我真的是在谈论我在谷歌上遇到的问题的能力。与其只从最初的几个谷歌搜索结果中选择一个来解决基本问题,我还必须筛选 bs 并深入挖掘只有半相关的线程才能得到我需要的东西。

标签: lisp common-lisp


【解决方案1】:

cons 单元是一个结构,它有两个部分,分别称为carcdr(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),那么您可以通过carcdr 获得12。你会像刚才描述的那样把它们重新组合在一起。也就是说,

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

【讨论】:

    猜你喜欢
    • 2011-12-09
    • 2016-12-20
    • 2021-11-25
    • 2018-07-20
    • 2023-02-25
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多