I have a Haskell function that computes subsets of a set.
subsets :: [a] -> [[a]]
subsets [] = [[]]
subsets (x:xs) = [zs | ys <- subsets xs, zs <- [ys, (x:ys)]]
Example of use:
*Main> subsets [1,2,3]
[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
If I add the definition:
ksubsets k xs = [ys | ys<-subsets xs, length ys==k]
I can compute the subsets of a set of n elements where each subset has exactly k elements
Example of use:
*Main> ksubsets 3 [1,2,3,4,5]
[[1,2,3],[1,2,4],[1,3,4],[2,3,4],[1,2,5],[1,3,5],[2,3,5],[1,4,5],[2,4,5],
[3,4,5]]
How could I create a more efficient function that generates the subsets of a set with n elements having exactly k elements but without generating all of the subsets. How do I only find the subsets of k elements.
Let's consider some recursive definitions, without going into code quite yet.
If you want to get every subset of size n , then you might pick an element, and append that to a subset of size n-1 . If we do that for each element, then we should get all subsets of size n . That's a useful starting point!
Let's put that into code now:
-- A base case:
subsetsOfSize 0 _ = [[]]
-- If there are no elements, there are no subsets:
subsetsOfSize _ [] = []
-- The case discussed above:
subsetsOfSize n (x:xs) =
[x : subs | subs <- subsetsOfSize (n-1) xs] -- ones starting with x,
++ subsetsOfSize n xs -- ones starting with other elements.
As for efficiency? That's left to you, since this does look a bit like work you should be doing on your own. What do you think is inefficient about this function? Here are a few ideas:
list
is m , and m is less than n, then subsetsOfSize n list = []
. Do we check for that already? ++
is not performant. What could we use instead? Is there a way to 'rephrase' this function?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.