以下(非最佳)代码为特定子集生成大小为N的所有子集。Haskell中所有大小为N的子集的快速获取
此代码有效,但正如我所说的,它非常不理想。使用中间列表来避免Set.insert的O(log(n))似乎没有帮助,因为之后将列表重新转换为集合的代价很大。设置
任何人都可以建议如何优化代码吗?
import qualified Data.Set as Set
subsetsOfSizeN :: Ord a => Int -> Set.Set a -> Set.Set (Set.Set a)
subsetsOfSizeN n s
| Set.size s < n || n < 0 = error "subsetOfSizeN: wrong parameters"
| otherwise = doSubsetsOfSizeN n s
where doSubsetsOfSizeN n s
| n == 0 = Set.singleton Set.empty
| Set.size s == n = Set.singleton s
| otherwise =
case Set.minView s of
Nothing -> Set.empty
Just (firstS, restS) ->
let partialN n = doSubsetsOfSizeN n restS in
Set.map (Set.insert firstS) (partialN (n-1)) `Set.union` partialN n
是否有'(:) [U] L''而不仅仅是'[U]一个特别的原因:L''? (同样,在'l''的定义中'(++)'和'(:)')。 – huon
是的,我更喜欢使用这种形式,因为我可以在where子句中写cons = uncurry ),concat = uncurry(++),并在cons [u] l替换[u]:l'后。 – zurgl