如何在Haskell中编写一个函数,该函数获取Int列表并返回该列表的所有连续子列表?

时间:2011-11-13 12:29:53

标签: list haskell

该函数需要获取整数元素的有序列表,并返回原始列表中相邻元素的所有组合。例如[1,2,3]将返回[[1,2,3],[1],[1,2],[2],[2,3],[3]]

请注意,[1,3]不应包括在内,因为13在原始列表中不相邻。

3 个答案:

答案 0 :(得分:4)

除了在inits中找不到tailsPrelude这一事实外,您可以将此功能定义为:

yourFunction :: [a] -> [[a]]
yourFunction = filter (not . null) . concat . map inits . tails

这就是它的作用,一步一步:

  • tails会删除已删除零个或多个起始元素的列表的所有版本:tails [1,2,3] == [[1,2,3],[2,3],[3],[]]
  • map initsinits应用于tails给出的每个列表,并且完全相反:它为删除了零个或多个结尾元素的列表的所有版本提供:{{1} }
  • 我希望您已经知道inits [1,2,3] == [[],[1],[1,2],[1,2,3]]:它会在concat列表中显示(++)(:)。您需要这样做,因为在concat [[1,2],[3],[],[4]] == [1,2,3,4]之后,您最终会得到一个列表列表,而您需要一个列表列表。
  • map inits . tails从结果中删除空列表。将有多个(除非您在空列表中使用该功能)。

您也可以使用filter (not . null)代替concatMap inits,这完全相同。它通常也表现得更好。


编辑:您可以使用concat . map inits进行定义 - 仅限功能:

Prelude

答案 1 :(得分:1)

所以,如果你需要连续和非空的答案(正如你在评论中注意到的那样)。

首先,让我们定义一个简单的子列表函数。

sublist' [] = [[]]
sublist' (x:xs) = sublist' xs ++ map (x:) (sublist' xs)

它返回所有具有空列表和非连续列表的子列表。所以我们需要过滤该列表的元素。像sublists = (filter consecutive) . filter (/= []) . sublist'

这样的东西

要检查列表的连续性,我们需要获得一对邻居(compactByN 2)并检查它们。

compactByN :: Int -> [a] -> [[a]]
compactByN _ [] = [[]]
compactByN n list | length list == n = [list]
compactByN n list@(x:xs)= take n list : compactByN n xs

最后

consecutive :: [Int] -> Bool
consecutive [_] = True
consecutive x = all (\[x,y] -> (x + 1 == y)) $ compact_by_n 2 x

我们有

λ> sublists [1,2,3]
[[3],[2],[2,3],[1],[1,2],[1,2,3]]

完成。 http://hpaste.org/53965

答案 2 :(得分:0)

除非,我错了,你只是要求数字的超集。

代码是相当自我解释的 - 我们的超集是通过构造尾部的超集两次来递归构建的,一次是我们当前的头部,一次没有,然后将它们组合在一起并与包含我们头部的列表组合在一起。 / p>

superset xs = []:(superset' xs) -- remember the empty list
superset' (x:xs) = [x]:(map (x:) (superset' xs)) ++ superset' xs
superset' [] = []