以下(非最优)代码为某个子集生成所有大小为 N 的子集。
该代码有效,但正如我所说,它非常不理想。使用中间列表来避免 Set.insert 的 O(log(n)) 似乎没有帮助,因为稍后将列表重新转换为 Set 的成本很高
有人可以建议如何优化代码吗?
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