[英]How can I write a function in Haskell that takes a list of Ints and returns all the contiguous sublists of that list?
該函數需要獲取一個有序的整數元素列表,並返回原始列表中所有相鄰元素的組合。 例如[1,2,3]
將返回[[1,2,3],[1],[1,2],[2],[2,3],[3]]
。
請注意,不應包含[1,3]
,因為1
和3
在原始列表中不相鄰。
除了在Prelude
找不到inits
和tails
之外,您還可以這樣定義函數:
yourFunction :: [a] -> [[a]]
yourFunction = filter (not . null) . concat . map inits . tails
這是它的工作,逐步進行:
tails
給出列表的所有版本,其中刪除了零個或多個起始元素: tails [1,2,3] == [[1,2,3],[2,3],[3],[]]
map inits
適用inits
於由給定的每個列表tails
,並不會完全相反:它給出了一個列表的所有版本的刪除零個或多個結束元素: inits [1,2,3] == [[],[1],[1,2],[1,2,3]]
concat
:它適用於(++)
列表中的(:)
: concat [[1,2],[3],[],[4]] == [1,2,3,4]
。 您需map inits . tails
,因為map inits . tails
map inits . tails
,您最終得到一個列表列表列表,而您想要一個列表列表。 filter (not . null)
從結果中刪除空列表。 將不止一個(除非您使用空白列表中的功能)。 您也可以使用concatMap inits
代替concat . map inits
concat . map inits
,它的作用完全相同。 它通常也表現更好。
編輯:您可以使用Prelude
-only函數定義它,例如:
yourFunction = concatMap inits . tails
where inits = takeWhile (not . null) . iterate init
tails = takeWhile (not . null) . iterate tail
因此,如果您需要連續且非空的答案(如您在評論中所注意到的)。
首先,讓我們定義一個簡單的子列表函數。
sublist' [] = [[]]
sublist' (x:xs) = sublist' xs ++ map (x:) (sublist' xs)
它返回帶有空列表和非連續列表的所有子列表。 因此,我們需要過濾該列表的元素。 sublists = (filter consecutive) . filter (/= []) . sublist'
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]]
除非我弄錯了,否則您只是在要求數字的超集。
該代碼是很容易說明的-我們的超集是通過兩次構建尾部的超集來遞歸構建的,一次是將當前頭放入其中,一次是不使用,然后將它們組合在一起,然后再包含一個包含我們頭部的列表。
superset xs = []:(superset' xs) -- remember the empty list
superset' (x:xs) = [x]:(map (x:) (superset' xs)) ++ superset' xs
superset' [] = []
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.