【问题标题】:LISP: Reversing a dotted listLISP:反转点列表
【发布时间】:2020-12-18 03:17:26
【问题描述】:

Common Lisp: A Gentle Introduction中有一个问题。问题是获取列表中的 last 元素而不是 cons 单元格。宏 LAST 在虚线列表中返回 cons cell。提出的问题是使用宏reverse 而不是last,但clispsbcl 都抛出错误。

(reverse '(a b c . d))
=> error

CLHS 文档说我们只能反转正确的列表(序列),而不能反转点列表或循环列表。

编辑

我使用LAST编写了程序。

(defun last-element (x)
 "x is a list with last element as dotted pair"
  (cdr (last x)))

我不知道在这种情况下如何使用reverse

【问题讨论】:

  • 自己定义一个?
  • 我应该使用reverse 定义我自己的函数。与应用编程和递归编程相关的章节尚未到来。另外,考虑使用nthcdrnth。但我们不能将其一概而论。我已经编辑了我的问题。请参考。
  • 附带说明,了解lastreverse &c 是函数而不是宏非常重要。这种差异对于理解 Lisp 非常重要。尤其值得思考的是,为什么不能将 reverse 写成宏。您可能还不知道为什么,但请记住这一点。

标签: list lisp common-lisp cons


【解决方案1】:

函数last 返回任何正确列表或点列表的最后一个cons 单元格,只要列表不是循环的。

听起来问题是关于练习 6.6:

使用 LAST 函数编写一个名为 LAST-ELEMENT 的函数,该函数返回列表的最后一个元素,而不是最后一个 cons 单元格。使用 REVERSE 而不是 LAST 编写 LAST-ELEMENT 的另一个版本。使用 NTH 和 LENGTH 编写另一个版本。

如果有此意图,练习将指定点列表输入。 When list is used in an unqualified way, it almost always means proper list。对于正确的列表last 将在cdr 中返回带有nilcons 单元格,例如(last '(a b c d) --> (d . nil),或者只是(d),所以正确列表的最后一个元素是最后一个cons 单元格的car

如果您想同时处理正确列表和点列表,您需要确定输入是哪个并相应地处理它:对于点列表,最后一个“元素”将是最后一个 cons 单元格的 cdr。为reverse 版本相应地处理输入意味着您必须在应用reverse 之前确定输入是正确的列表还是虚线列表。在使用reverse 之前,您可以编写一个函数将点列表转换为正确的列表。

从技术上讲,the Standard does not consider the atom which terminates a dotted list to be one of its elements

元素 n。 1. (of a list) 一个对象,它是构成该列表的 conses 之一的汽车。

对于像(a b c d) 这样的正确列表,nil 是终止原子(因为(a b c d)(a b c d . nil) 相同),(d . nil) 是最后一个缺点; d 是最后一个 conscar,因此是列表的最后一个元素。对于像(a b c . d) 这样的虚线列表,d 是终止原子,(c . d) 是最后一个cons。因为c 是最后一个conscar,所以c 是虚线列表中标准中定义的最后一个真正的元素。说d(a b c . d) 的最后一个成员 可能更准确。

但是,Common Lisp: A Gentle Introduction 中的练习 6.6 仅适用于正确的列表。

【讨论】:

  • 谢谢。这正是混乱。练习 6.6 提到 LAST 返回 cons cell 并要求我们编写一个函数 LAST-ELEMENT 返回 last element。所以,很自然,我认为输入列表将以dotted-pair 结尾。这是我的误解。现在,我不得不担心将不正确的列表(点列表)转换为正确的列表。再次感谢。
  • @SreekumarR -- “如果结果是NIL...”:正确列表的最后一个元素不是nil。对于(a b c d),最后一个元素是dnil 是终止原子。
  • @SreekumarR -- 问题希望last-element 返回列表的最后一个元素:正确的列表last 函数返回列表的最后一个 cons,而不是该列表的最后一个元素。列表的最后一个元素是该列表的最后一个conscar。实际上,last 可以接受一个整数参数并返回列表的最后一个nconses。 IAC,'(a b c d)的最后一个conscons'(d . nil),最后一个元素是(car '(d . nil)),即dnil 不是列表的元素,'(d . nil) 也不是。
  • @SreekumarR -- 列表'(a b c d) 只是conses 的序列;它与'(a b c d . nil) 相同,但nil 不是列表中的元素
  • 非常感谢您不仅澄清了问题,而且还提供了解释。这是我在学习时的初步想法,但本书前面一些示例中的dotted list 让我感到困惑。
猜你喜欢
  • 2012-02-07
  • 2015-04-17
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 2020-02-14
相关资源
最近更新 更多