Haskell,重复+排列组合

时间:2016-01-30 15:50:54

标签: haskell

假设我有一个包含元素的列表,例如[1,2,3,4,5,6,7,8]。 我想创建长度为N的这些元素的所有排列。

因此,对于N = 4,它将是 [[1,1,1,1],[1,1,1,2],[1,1,2,1],[1,2,1,1],[2,1,1,1],..]等等。

comb :: Int -> [a] -> [[a]]
comb 0 _ = [[]]
comb _ [] = []
comb m (x:xs) = map (x:) (comb (m-1) xs) ++ comb m xs

现在,为了首先获得此列表,我找到了重复列表的所有组合, 所以[[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,1,4],[1,1,1,5],...]和每个列表我找到所有排列,如果列表中没有排列,我将它添加到列表中。

permutations1 :: Eq a => [a] -> [[a]]
permutations1 []   = [[]]
permutations1 list = [(x:xs) | x <- list, xs <- permutations1 $ delete1 x list]

delete1:: Eq a => a -> [a] -> [a]
delete1 _ [] = [] 
delete1 a (b:bc) | a == b = bc 
                 | otherwise = b : delete1 a bc

这就是我得到通缉答案的方式。

我知道它确实(非常)糟糕,但我不太了解haskell足以编写将这些函数组合起来的函数。

1 个答案:

答案 0 :(得分:10)

这称为带有替换的采样。在haskell中,您可以使用replicateM和列表的monadic行为(即非确定性计算)

\> import Control.Monad (replicateM)
\> length $ replicateM 4 [1..5]   -- should output 5^4
625
\> replicateM 4 [1..5]
[[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,1,4],[1,1,1,5],[1,1,2,1],[1,1,2,2],[1,1,2,3],[1,1,2,4],[1,1,2,5]] ....

如果您想从5号人口中选择4号样本进行替换,那么对于4个项目中的每一个,您有5个选择;所以你复制每次[1..5] 4次,因此replicateM 4

Monad type class(即M部分)表示您应该能够绑定这些中间值。

The list instance of monad type class模型非确定性。即它表示每个项目都是非确定性的,但它可以是[1..5]值中的一个,并且绑定它们一起采用所有非外部产品 - 确定性的价值观;因为如果你有4个项目,每个项目取5个可能的值,那么你有5^4个可能的最终输出。