元のリストXにはn個のアイテムがあります。すべてのアイテムがサブリストに表示されるかどうかにかかわらず、2 ** nの可能なサブリストがあります。各アイテムは、可能なサブリストの列挙にビットを追加します。このnビットのビットワードの列挙を表示できます。
k個のアイテムを含むサブリストのみが必要なので、正確にkビットが設定されたビットワードに関心があります。実際のアルゴリズムでは、Xから最初の要素を選択(または選択しない)してから、選択したアイテムの累積数を考慮して、Xの右端のn-1サブストリングに再帰することができます。Xリストは順番に処理されるため、Yリストも順番に処理されます。
#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;
}
再帰を削除することは、読者の練習問題として残されています。いくつかの出力:
plasser@pisbak:~/hiero/src$ ./a.out 3 ABBA
BBA
ABA
ABA
ABB
Count=4
plasser@pisbak:~/hiero/src$