Directly construct each subset of the previous subset. It is also easy to imagine the subset as a 128-bit number (although, obviously, most of the values will not be mapped to the qualification subset, and I don’t know if the value of 128 in the question was real or just an example.) This is of course the first approach I would use ; if it works, all O (1) and storage costs are not extreme (16 bytes for indexes instead of 4).
If you really want to store short indexes for subsets, I would use the following recursion, where S (n, k) represents all the subsets (or subset counts) of size & le; k of values <n
s(n,0) = { {} }
s(n,k) = (s(n-1,k-1) ⊙ {n}) ⋃ s(n-1,k) if n ≥ k > 0
s(n,k) = {} if n < k
where is the operator P ⊙ S P ⊙ S means “Add S to each element of P ” (and therefore the result will be exactly the same size as P ). So, considered as a counting algorithm, we get:
S(n,0) = 1
S(n,k) = S(n-1,k-1) + S(n-1,k) if n ≥ k > 0
S(n,k) = 0 if n < k
The second recursion can be re-expressed as:
S(n,k) = Σ n i=k S(i-1,k-1)
(which would look better with jsMath, grrr.)
Another way to say that we will generate sets in order by the largest element, so we start with the set {0...k-1} , then all sets with {k} as the largest element, then all those {k+1} etc. In each group of sets, we recursively find a series with (k-1) , start again with the lowest maximum value and work up to one less than the maximum value that we just selected.
So, we can find out what is the largest value in the indexed set for the index in S(n,k) by sequentially subtracting S(i-1, k-1) for i from k to n until the result is negative; then add {i} to the result set; decrease k by 1 and repeat with n now set to i-1 .
If we pre-copy the corresponding tables S(n,k) , of which there are about 640 real combinations, we can use the binary search instead of iteration to find i at each step, so the calculation takes time k log(n) , which is not terrible .