2

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

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

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

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

4

2 回答 2

4

如果没有对序列内容的其他限制,这是不可能的。例如,如果要求它们按排序顺序排列,您可以这样做。但是给定两个无限的、任意顺序的序列 A 和 B,你永远无法确定 A[0] 不在 B 中,因为你将永远继续搜索,所以你永远无法开始搜索对于 A[1]。

于 2013-06-23T19:49:34.997 回答
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))))

好吧,这仍然是假设列表数量有限......这应该是合理的。

于 2013-06-23T19:56:20.810 回答