The original list X contains n elements. There are 2 ** n possible subscriptions, since each element will or will not appear in the sublist: each element adds a little to the list of possible subscriptions. You can view this enumeration of a bitword of n bits.
Since you only need sublists with k elements, you are interested in broken words with exactly set k bits. A practical algorithm can select (or choose not) the first element from X, and then list the rightmost n-1 substring X, taking into account the accumulated number of selected elements. Since list X is processed in order, list Y will also be in order.
#include <stdio.h> #include <string.h> unsigned pick_k_from_n(char target[], char src[], unsigned k, unsigned n, unsigned done); unsigned pick_k_from_n(char target[], char src[] , unsigned k, unsigned n, unsigned done) { unsigned count=0; if (k>n) return 0; if (k==0) { target[done] = 0; puts(target); return 1; } if (n > 0) { count += pick_k_from_n(target, src+1, k, n-1, done); target[done] = *src; count += pick_k_from_n(target, src+1, k-1, n-1, done+1); } return count; } int main(int argc, char **argv) { char result[20]; char *domain = "OmgWtf!"; unsigned cnt ,len, want; want = 3; switch (argc) { default: case 3: domain = argv[2]; case 2: sscanf(argv[1], "%u", &want); case 1: break; } len = strlen(domain); cnt = pick_k_from_n(result, domain, want, len, 0); fprintf(stderr, "Count=%u\n", cnt); return 0; }
Removing recursion remains as an exercise for the reader. Some conclusion:
plasser@pisbak :~/hiero/src$ ./a.out 3 ABBA BBA ABA ABA ABB Count=4 plasser@pisbak :~/hiero/src$
wildplasser
source share