【问题标题】:Linearly recursive list-difference function in Common LispCommon Lisp 中的线性递归列表差分函数
【发布时间】:2010-10-11 06:34:36
【问题描述】:

为了好玩,我正在浏览 this 教程,却被他说的最后一句话卡住了,“练习:给出联合和差异的线性递归实现。” (用于列表)

联合,没有汗水。

差异,汗水。

尝试看起来像这样。 . .

(defun list-diff (L1 L2)
  (cond
    ((null L1) L2) 
    ((null (member (first L1) L2)) (cons (first L1) (list-diff (rest L1) L2)))
    (t (list-diff (rest L1) L2))
  )
)

现在,它返回 L1 中所有不在 L2 中的元素,但它只返回所有 L2(显然)。同样,如果我将第 3 行中的 L2 更改为“nil”,那么它只会返回不在 L2 中的所有 L1,但不返回 L2。

我对变通办法的尝试看起来并不递归,当它们出现时,我最终会遇到堆栈溢出(就像我尝试在某处调用 (list-diff L2 L1) 一样)。

他的任何其他练习,例如列表交集,只需要遍历 L1 的元素。在这里,我想从 L2 中删除关键元素,或者运行 (list-diff L2 L1) 然后合并两者的结果,但这不再是真正的线性递归了。

想法?

(不是作业,真的。我只是想尝试看看一些 LISP 以获得乐趣。)

编辑:根据响应正确执行此操作的函数是:

(defun list-diff (L1 L2)
  (cond
    ((null L1) nil)
    ((null (member (first L1) L2)) (cons (first L1) (list-diff (rest L1) L2)))
    (t (list-diff (rest L1) L2))
  )
)

【问题讨论】:

  • 嗯,是的,只是 return l1 是第一个子句。
  • 风格:在第二个子句中编写测试而不调用 null 并交换第二个和第三个子句的结果部分。稍微简化了代码。
  • 风格:不要使用 C 格式。将括号放在函数的末尾。使用自动缩进、括号高亮等来获得正确的代码结构。
  • Rainer -- 谢谢。也许您可以发布一个包含您所做更改的答案,以便我可以看到它们?

标签: algorithm recursion lisp common-lisp


【解决方案1】:

set difference 操作 L1 \ L2 被定义为所有元素 e 使得 e 在 L1 中但 e 不在 L2 中。所以在我看来你的第二次尝试实际上是正确的:

同样,如果我更改 L2 行 3 到“nil”,然后它只返回所有 不在 L2 中的 L1,但没有 L2.

您似乎正在尝试计算 symmetric difference,尽管我不清楚这是练习要求的内容。

如果你想聪明一点,你可以将第三个列表传递给函数作为累加器。当 L1 有元素时,将第一个元素推入累加器(并递归调用)(null (member (first L1) L2))。当 L1 为空时,根据累加器列表检查 L2 的元素,做同样的事情。当 L1 和 L2 为空时,返回累加器列表。

【讨论】:

  • 哦,好吧。那么,我对集合差异的定义是错误的。我在考虑对称差异。是的,我的第二个版本做得很好。我曾考虑过使用蓄能器,但在他做那个练习时还没有引入。
【解决方案2】:

在 Lisp 中,这是“设置差异”的定义:

set-difference list1 list2 &key (test #'eql) test-not (key #'identity)
   Function
   Returns a list of elements of list1 that do not appear in list2. 

这是你修改后的实现:

(defun list-diff (L1 L2)
  (cond
    ((null L1) L1)
    ((member (first L1) L2) (list-diff (rest L1) L2))
    (t (cons (first l1) (list-diff (rest l1) l2)))))

【讨论】:

    猜你喜欢
    • 2018-05-16
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多