假设我有一个包含元素的列表,例如[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足以编写将这些函数组合起来的函数。
答案 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
个可能的最终输出。