給定一個集合,輸出它的所有子集
阿新 • • 發佈:2019-02-05
題目:集合是由大字字母(A-Z)組成的,要求輸出集合的所有子集,每個子集一行,不能使用遞迴。
例如 “ABD”的子集:
NULL(空集)、A、B、C、AB、AC、BC、ABC(共8個)
這個題可以用點陣圖的思想做。
比如集合{A,B} 對應位向量v=000...00011(26維)
那麼A表示1,B表示2,[0,3]迴圈(3是B在字母表的位置2+1計算得):
0 & v = 0 輸出NULL
1& v =1 (000...0001)輸出A
2&V = 2 (000...0010)輸出B
3&V = 3 (000...0011)輸出AB
因此,我們可以得到下面的程式碼:
#include <stdio.h> #include <string.h> #include <math.h> #define N 26 int array[N / 32 + 1];//只用了一個int char *p = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int maxElement(const char *s)//計算字串最大值,例如ABDF最大為F,位於字母表第6個,輸出6 { int res = s[0]; for (int i = 1; s[i]; ++i) { if (s[i] > res) res = s[i]; } return res-'A'+1; } void set(int x) { array[x >> 5] |= (1 << (x & 0x1F)); } void Initialization(const char *s) { int i; for (i = 0; s[i]; ++i) set(s[i] - 'A');//'A'在第一位 } void subSet(const char *s, const int n) { int i,j; int x = pow(2.0, maxElement(s)); int tmp = 0; int mask = 1; Initialization(s); printf("NULL\n"); for (i = 1; i < x; ++i) { tmp = i & array[0]; if (tmp<i) continue; mask = 1; for (j = 0; j < N;++j) { if (mask & tmp) printf("%c ", p[j]); mask = mask << 1; } printf("\n"); } } int main() { char *t = "ABDF"; subSet(t, 4); return 0; }