列表列表Haskell的交集

时间:2017-05-11 14:32:56

标签: haskell

我必须编写一个返回两个以上列表的间隔的函数

Ex: intersection[[1,5,3,11],[1,5,2,11],[5,3,2,11]] = [5, 11]
intersection:: (Eq a) => [[a]] -> [a]
intersection= undefined

我发现存在一个函数intersect :: Eq a => [a] - > [a] - > [a](但它仅适用于2个列表:)

3 个答案:

答案 0 :(得分:3)

当您注意到a -> a -> a形式的函数时,您可能正在处理可以与monoid一起使用的函数,这意味着您可以使用折叠。

在你的情况下,intersection []并没有合理的输出,所以你应该使用需要非空输入列表的折叠函数,例如foldr1

因此,一个简单的实现方式是:

intersection:: (Eq a) => [[a]] -> [a]
intersection = foldr1 intersect

答案 1 :(得分:2)

两组的交集是关联(和交换,但在这里不太重要)。即:

intersect(A, B, C) = intersect(intersect(A,B), C) = intersect(A, intersect(B, C))

这意味着你做交叉操作的顺序并不重要,结果不会改变。

因此,在Haskell中,您可以利用foldl1函数在所有列表中应用intersect函数:

> import Data.List
> foldl1 intersect [[1,5,3,11],[1,5,2,11],[5,3,2,11]]
[5,11]

答案 2 :(得分:1)

简单方法专家提示:

专业提示:

两个列表的交集是显而易见的。

3个列表的交集是第3个列表与前2个列表的交集。

那么你要做的是记住当前的交叉点结果并将其与下一个列表相交,直到你的列表用完或直到你的交叉点为空。

在复杂性方面更好的方法是使用合并排序方法。

威胁列表中列出了列表元素,而不是理解,使用元素相交并返回它们的交集。

合并操作也是一个交叉点。

自从我与Haskell有任何关系以来已经很长时间了,所以不幸的是我无法为您提供代码示例。