我编写了代码来查找许多序列的常见元素:
(defn common [l & others]
(if (= 1 (count others))
(filter #(some #{%1} (first others)) l)
(filter #(and (some #{%1} (first others)) (not (empty? (apply common (list %1) (rest others))))) l)))
可以找到有限序列的第一个常见元素,如下所示:
(第一次(普通[1 2] [0 1 2 3 4 5] [3 1])) - > 1
但是如果任何序列是无限的,它就很容易在无限搜索上发送:
(第一(普通[1 2] [0 1 2 3 4 5](范围)))
我理解为什么会这样,我知道我需要以某种方式使计算变得懒惰,但我还不知道如何最好地做到这一点。
这是我的问题:如何重新编写代码(或者可能使用完全不同的代码)来查找多个序列的第一个公共元素,其中一个或多个序列可能是无限的。
答案 0 :(得分:4)
如果没有对序列内容的一些其他限制,这是不可能的。例如,如果要求它们按排序顺序排列,则可以执行此操作。但是给定两个无限的,任意排序的序列A和B,你不能确定A [0]不在B中,因为你会永远搜索,所以你永远无法开始搜索对于A [1]。
答案 1 :(得分:0)
我可能会做类似
的事情(fn [ & lists ]
(filter search-in-finite-lists (map (fn [ & elements ] elements) lists)))
诀窍是一次性在所有列表中逐级搜索。在每个级别,只需要搜索每个列表的最后一个元素是否在任何其他列表中。
我想如果列表是无限的并且没有匹配,我们应该无限搜索。但是,您可以在过滤器之前添加(取X列表)以施加最大值。像这样:
(fn [ max & lists ]
(filter search-in-finite-lists (take max (map (fn [ & elements ] elements) lists))))
嗯,这仍然是假定有限数量的列表......这应该是合理的。