最长的公用子列表

时间:2018-10-22 10:23:13

标签: haskell

我需要一个函数f :: Eq a => [[a]] -> [a],该函数返回提供的每个列表中最长的子列表。例如f [[1,2,3], [0,1,3], [1,3,4]] = [1,3]。 [1,3]被定义为[1,2,3]的子列表,因此子列表的元素不必在超级列表的相邻位置。

到目前为止,我一直想让函数成为一个函数:findCombinations :: [a] -> [[a]],它接受​​一个列表并返回该列表中所有可能的元素组合。例如,[1,2,3] -> [[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]],然后对超级列表的每个子列表使用该函数,以便为每个子列表找到所有可能的组合,然后找到出现次数最多的组合,但是我仍然坚持执行。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

对于您的findCombinations函数,可以采用以下方法。

  • []只有一个子列表,即[]本身
  • x:xs的子列表具有两种形式:
    • xs的子列表
    • xs的子列表,其中x已添加到每个子列表的前面

您可以通过首先定义一个函数addToAll :: a -> [[a]] -> [[a]](例如addToAll 2 [[1,5],[],[8,5,6]] = [[2,1,5],[2],[2,8,5,6]])来开始对此进行编码。

答案 1 :(得分:0)

好,您只需使用foldl1应用的Data.List.intersect即可完成。例如;

Prelude> foldl1 Data.List.intersect [[1,2,3], [0,1,3], [1,3,4]]
Prelude> [1,3]

Data.List是一个非常常见的库,它的许多居民在Prelude中是默认的,例如foldl1。因此,从中导入intersect并不重要。但是,intersect本身是一个非常简单的代码,您可以自己或steal it from the definition来简单地实现它。来吧;

Prelude> let isect xs ys = filter (\e -> any (== e) xs) ys
Prelude> foldl1 isect [[1,2,3,4,5,6,7,8,9], [-3,-2,-1,0,1,2,3,4,5], [3,4,4,4,5,6,7]]
[3,4,5]

所以,您去。您的图书馆不可知功能是。

f :: Eq a => [[a]] -> [a]
f = foldl1 isect