【发布时间】: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