列表的交集Haskell

列表的交集Haskell,haskell,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](但它仅适用于两个列表:)简易方法专业提示: 专业提示: 两个列表的交集是显而易见的 3个列表的交集是第3个列表与

我必须编写一个函数,返回两个以上列表的交互操作

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](但它仅适用于两个列表:)

简易方法专业提示:

专业提示:

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

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

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

就复杂性而言,更好的方法是使用类似合并排序的方法

当您的威胁列表类似于列表中的元素,而不是理解时,请在元素上使用交集并返回它们的交集

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


我已经很久没有和Haskell有任何关系了,所以很遗憾,我无法向您提供代码示例

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

在您的情况下,
intersection[]
实际上没有合理的输出,因此您应该使用需要非空输入列表的折叠函数,例如

因此,一个简单的实施方法是:

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

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

这意味着不管你以什么顺序进行交叉操作,结果都不会改变

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

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

这里有一个漂亮的
+
操作符,它可以将两个数字相加,但是如果我想把整个列表加起来怎么办?看到JavaScript标记中的一些面在这里执行
.reduce()
技巧很酷。嗯……我想
foldr1
是MOAR(所有Reduces之母)+@热度哈哈,是的。我一直在学习Haskell,以便识别何时在JavaScript中使用某些模式。这是一个很好的教训。你的解决方案中涉及的幺半群是什么?我想不出这里有
mempty
。@Jean BaptistePotonnier这里没有使用幺半群,只有一个的一半。可以使用幺半群的
mappend
部分进行折叠。我的第一句话只是陈述了一个有用的直觉。@Jean BaptistePotonnier
Endo
似乎是一个合理的候选人。没有newtype包装器,
mempty=id;mappend=()
。将
foldMap intersect
应用于列表
[x,y,z]
将为您提供
intersect x。我很高兴。相交z
。从那里到实际需要的功能只需几步。
> import Data.List
> foldl1 intersect [[1,5,3,11],[1,5,2,11],[5,3,2,11]]
[5,11]