I have this code which generates power set of an array of size 4 (number is just example, less combinations to write...).
#define ARRAY_SIZE 4
unsigned int i, j, bits, i_max = 1U << ARRAY_SIZE;
int array[ARRAY_SIZE];
for (i = 0; i < i_max ; ++i) {
for (bits = i, j = 0; bits; bits >>= 1, ++j) {
if (bits & 1)
printf("%d", array[j]);
}
}
Output:
{}
{1}
{2}
{1, 2}
{3}
{1, 3}
{2, 3}
{1, 2, 3}
{4}
{1, 4}
{2, 4}
{1, 2, 4}
{3, 4}
{1, 3, 4}
{2, 3, 4}
{1, 2, 3, 4}
I need that output to be like this one:
{1}
{2}
{3}
{4}
{1, 2}
{1, 3}
{1, 4}
{2, 3}
{2, 4}
{3, 4}
{1, 2, 3}
{1, 2, 4}
{1, 3, 4}
{2, 3, 4}
{1, 2, 3, 4}
So it has to be ordered like that. I can't do that ordering after that algorithm ends, I have to use every combination in every iteration, so It has to generate that combinations already ordered. Can someone help me out? I think I was thinking about everything...
EDIT: That final output should be without empty set, but it's not priority.
I used this answer to make following code:
Basically you need to print
nCr
sequences for allr
See here
Here's a version that goes down to the metal with bit-twiddling. It uses a modified version of the famous Hackers' Delight
snoob()
function that generates the next greater subset with the Same Number Of One Bits. See the Chess Programming Wiki (a source of many such bit-twiddling routines).Live Example with output in lexicographic order (bonus feature)
Use a buffer array and then sort it using
qsort
?I used a
i_max*5
elements array : 4unsigned int
for the values (0 means empty, 1 to 4 otherwise) and a final unsigned int for the subset length. Then, you just have to roll with your custom comparator. If you want to a more streamlined algorithm, take a look at insertion sort : http://en.wikipedia.org/wiki/Insertion_sortOutput:
Code:
The code:
(I know some people don't like raw arrays / pointers, but it's so much easier to get great performance for this problem with that as opposed to pretty containers)
And the calling function:
powerSet("1234", 4)
prints:Test.
Write a function to generate all items of a fixed size. Note that the first such item is 1,..,k while the last is (n-k+1),..,n. This is very simple, you basically have to reimplement basic counting: you increment the last "digit", until you reach n. Then you reset to 1 and continue in the same fashion to its left.
Then just have k run from 1 (0) to n.
Here is one proposal for the internal algorithm. It's rather ugly, though.