潜在无限序列的第一个共同元素

时间:2013-06-23 19:28:09

标签: clojure lazy-evaluation

我编写了代码来查找许多序列的常见元素:

(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](范围)))

我理解为什么会这样,我知道我需要以某种方式使计算变得懒惰,但我还不知道如何最好地做到这一点。

这是我的问题:如何重新编写代码(或者可能使用完全不同的代码)来查找多个序列的第一个公共元素,其中一个或多个序列可能是无限的。

2 个答案:

答案 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))))

嗯,这仍然是假定有限数量的列表......这应该是合理的。