[英]All possible sublists as pairs haskell
有點不確定如何恰當地說這個,所以請耐心等待!
給定一個列表[1,2,3,4]我想要一個列表元組列表,如下所示:[([1],[2,3,4]),([1,2],[3,4] ]),([1,2,3],[4])]。
問題的B部分也是在子列表中獲得所有可能的排序。 所以在第一個元組的情況下,我希望2 3 4按順序243,324,432,423 ......
是的,我喜歡非決定論。
import Data.List (inits, tails, permutations)
import Control.Arrow (first, second)
parta :: [a] -> [([a], [a])]
parta [] = []
parta xs = init . tail $ zip (inits xs) (tails xs)
對於b部分,我不確定你是否想要[([1],[2,3,4]), ([1],[3,4,2]), ...]
或[([1],[[2,3,4],[3,4,2],...]), ...]
。 如果是后者,那么
partb :: [a] -> [([a], [[a]])]
partb = map (second permutations) . parta
編輯:哦,但你想要前者。 在這種情況下
partb :: [a] -> [([a], [a])]
partb = map (uncurry zip . first repeat . second permutations) . parta
最后編輯:因為我已經使用了Control.Arrow中的一些函數,我會注意到 zip (inits xs) (tails xs)
也可以寫成(inits &&& tails) xs
,但我不確定這樣更清楚。
第1步 :找到一個合適的方法將列表拆分為兩個列表的元組。
Hoogling [a] -> ([a], [a])
我們發現splitAt :: Int -> [a] -> ([a],[a])
import Data.List (splitAt, permutations) -- we'll need to permute for part B
第2步 :將其寫入一個索引。
splitPair xs = splitAt 1 xs
第3步 :使其對許多索引不確定地工作。
splitPairs xs = do index <- [1..length xs-1]
return $ splitAt index xs
看看單選功能如何輕松轉換為非確定性選擇功能? (這與列表理解一樣容易編寫:)
splitPairs' xs = [splitAt i xs | i <- [1..length xs-1]]
splitPairsPerms xs = do (ys, zs) <- splitPairs xs
ys' <- permutations ys
zs' <- permutations zs
return $ (ys', zs')
列表monad非常適合編寫簡單函數並將它們轉換為非確定性函數。 然而,這種方法並不總是最有效的。 在我的例子中,我使用了length xs
和splitAt i xs
,它們必須遍歷列表的長度才能執行它們的任務(好吧, splitAt
只需要遍歷索引i,這平均是索引i的一半長度。列表,如此相同的數量級)。 如果性能很重要,那么轉換為序列可能是明智之舉。
在第一種情況下,您只需將列表拆分為兩個。 第一個將包含輸入,第二個將最初為空。 然后從第一個元素中取出一個元素,並將其放在第二個元素中,直到第一個元素為空。
magic x = magic' x []
where
magic' [] y = [[[], y]]
magic' (x:xs) y = [[reverse y, (x:xs)]] ++ magic' xs (x:y)
接下來的問題是:它只是元素的簡單排列。
perm x = perm' x [] []
where
perm' [] [] prefix = [prefix]
perm' [] rest prefix = []
perm' (x:xs) rest prefix =
perm' (xs++rest) [] (x:prefix) ++
perm' xs (x:rest) prefix
我最喜歡Dan的答案,因為我認為這是最有啟發性的。 但是,如果你擔心splitPair
的效率,那么我認為這個相當直接的定義工作正常:
splitPair :: [a] -> [([a],[a])]
splitPair [] = ([],[]) : []
splitPair a@(x:xs) = ([],a) : map (\(u,v)->(x:u,v)) (splitPair xs)
此定義與原始問題陳述略有不同,因為它返回第一個或最后一個列表為空的對。 這與大多數列表函數(如tails
或inits
的定義更為一致:
> splitPair [1,2,3,4]
[([],[1,2,3,4]),([1],[2,3,4]),([1,2],[3,4]),([1,2,3],[4]),([1,2,3,4],[])]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.