【问题标题】:Return a list of characters from a mixed list从混合列表中返回字符列表
【发布时间】:2023-03-02 23:19:01
【问题描述】:

我正在尝试编写一个 Lisp 函数来从列表(包含整数、字符等)中返回一个字符列表(不重复)。我仍然是 Lisp 的初学者,开始时遇到了麻烦。我们的教授提到使用原子,但我不明白她的意思。问题来了:

"编写一个接受列表作为输入参数的 lisp 函数(该列表混合了整数、小数、 字符和嵌套列表)并创建一个列表,其中包括原始列表中的所有字符,没有任何 复制。示例程序输出如下所示:

  1. ‘((z f) (b a 5 3.5) 6 (7) (a) c) -> (z f b a c)
  2. ‘( (n) 2 (6 h 7.8) (w f) (n) (c) n) -> (h w f c n) "

【问题讨论】:

  • 示例不包含任何字符。它们包含一些符号;这些符号的名称是长度为 1 的字符串。字符A 在(ANSI 通用)Lisp 语法中编码为#\A。哈希反斜杠 A.
  • 在 Lisp 中,没有“十进制”类型。 3.5 是表示 浮点 数的标记。打印的符号是十进制的,但浮点数在内部不是十进制的。有时,新程序员在做数字工作时认为浮点数是十进制的;然后当结果不符合纸笔十进制算术时,他们会感到惊讶。
  • atom 是一个函数,如果它的参数不是(非空)列表,则返回 t (true)。因此,当遍历一个列表时,它可以用来确定当前元素是否是应该考虑收集的东西(除非已经看到),或者它是否是一个本身应该被遍历的子列表。

标签: lisp common-lisp


【解决方案1】:

你的作业所称的“字符”实际上是名称长度为 1 的符号。似乎你可以在脑海中将“字符”一词替换为“符号”并使用它。

原子是任何不是 cons 的东西——任何非空列表都由 conses 链组成。例如,符号、数字、字符串和nil 都是原子。

一个 cons(实际上是一个 cons 单元格)是一个简单的数据结构,可以容纳两个东西。在一个列表中,每个 cons 的第一件事是一些列表元素,第二个是指向下一个 cons 的指针或 nil。您还可以将列表作为列表元素;那么第一件事也是指向列表的指针。这将正式成为一棵树。 cons 的第一件事的存取函数称为carfirst,另一件事的存取函数称为cdrrestCarcdr 有点陈旧,主要用于将 cons 单元格视为树节点时使用,而 firstrest 更现代,主要用于将 cons 单元格视为列表时链环。

您可以使用函数atom 测试一个事物是否是一个原子。如果它不是原子,则它是一个包含至少一个元素的列表。

你的作业有几个部分:

  • 走在树上查看每个元素。这可以通过递归来完成,或者通过在一个方向上循环并在另一个方向上递归来完成。
  • 保留您已经找到的符号列表。
  • 如果您查看的元素是一个符号(名称长度为 1...),请检查它是否是新的,如果是,请将其添加到您的列表中。
  • 最后返回那个列表。

一个有用的习惯用法是使用pushpushnew,它们将新元素放在列表的前面,reverse 放在最后。

【讨论】:

  • 我不想破坏作业,但你能举个例子来说明如何在递归中更新和返回结果列表。不知何故,在我不充分的尝试中,我总是得到nil,即使trace 表明找到了正确的原子。
  • 当使用子树递归调用函数时,它将仅返回来自该子树的符号列表。您需要将其与当前级别的列表相结合,例如。 G。通过appendremove-duplicates
  • 那意味着pushnew 方法只适用于迭代解决方案?
  • 它修改了一个地方,所以只有当你有一些地方可以从多个递归调用中访问时才有意义。一种方法是使用内部函数进行递归。
  • 当然也可以先展平,再过滤,再去重复。
猜你喜欢
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 2012-09-06
  • 2015-04-03
  • 1970-01-01
相关资源
最近更新 更多