The code below is an implementation of purely recursive solution to find a powerset of any given set. The input set is a string, and the output – array of strings. Both of them are wrapped into a structure for convenience. The underlying algorithm is pretty common one. The recursive function executes exactly 2^n – 1 times.
I’ve intentionally removed all memory allocation error checking to make the snippet shorter.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct set {
char* data;
int size;
} Set;
typedef struct pset {
char **data;
int size;
} PSet;
Set *initSet(char *str) {
Set *set;
set = malloc(sizeof(Set));
set->data = calloc(strlen(str) + 1, 1);
strcpy(set->data, str);
set->size = strlen(str);
return set;
}
PSet *initPSet(const Set* sset) {
// wrapper for recursive function getPSet
void getPSet(PSet *pset, const Set *inputStr, int buffer, int index);
PSet *pset = malloc(sizeof(PSet));
pset->data = malloc (sizeof(char *) * (1 << sset->size));
// empty set is a subset of any set
pset->data(pset->size) = calloc(2, 1);
strcpy(pset->data(pset->size), "");
pset->size = 1;
// in case the input set is empty return a set with just one element
if (sset->size != 0)
getPSet(pset, sset, 0, 0);
return pset;
}
void getPSet(PSet *pset, const Set *set, int buffer, int index) {
//allocating place for a new subset
pset->data(pset->size) = calloc(strlen(pset->data(buffer)) + 2, sizeof(char));
strcpy(pset->data(pset->size), pset->data(buffer));
pset->data(pset->size)(strlen(pset->data(buffer))) = set->data(index);
pset->size++;
// local variable pos keeps track of a position of a prefix stored in pset for future recurrent calls
int pos = pset->size - 1;
index++;
if (index >= set->size) return;
getPSet(pset, set, buffer, index);
getPSet(pset, set, pos, index);
}
int main () {
Set *sset = initSet("abcd");
PSet *pset;
pset = initPSet(sset);
for (int i = 0; i < pset->size; ++i) {
printf("{%s}n", pset->data(i));
}
return 0;
}