在解决问题26(“生成从列表的N个元素中选择的K个不同对象的组合”)时,我提出了以下实现:
combi :: Int -> [a] -> [[a]]
combi 0 _ = [[]]
combi n ys@(x:xs) = [ y:xs' | y <- ys, xs' <- combi (n-1) xs ]
建议的解决方案之一是:
combinations :: Int -> [a] -> [[a]]
combinations 0 _ = [ [] ]
combinations n xs = [ y:ys | y:xs' <- tails xs
, ys <- combinations (n-1) xs']
虽然有些类似,但提供的解决方案比我的快得多。
为什么?
答案 0 :(得分:4)
您的解决方案不正确。例如。 combi 2 [1,2]
为[[1,2], [2,2]]
而不是[[1,2]]
。
您的递归案例始终会计算combi (n-1) xs
,其中length xs == length ys - 1
。在正确的解决方案中,xs'
的长度随着每一步而减少。这似乎是一个小差异,但递归使它复杂化。