一个集合S的分割就是把S分解成若干个子集S1, S2, ..., Sp,使得S1 U S2 U ... U Sp = S,但对任意两个不同的子集Si与Sj而言,两集合的交集为空。换句话说,集合的分割,就是把该集合分解成若干相互分离的子集。举例来说,{1, 2, 3}的分割就有{1}, {2}, {3}; {1, 2}, {3}; {1, 3}, {2}; {2, 3}, {1}; {1, 2, 3}这5种。请写一个程序,读入n,列出{1, 2, 3, ..., n}的所有分割方式。
#include <iostream> #include <algorithm> #include <iterator> using namespace std; #define ALWAYS 1 void display(int *, int*, int); void set_partition(int n) { int *code, *maxi, *array; int i, j; code = (int *)malloc(sizeof(int) * n); maxi = (int *)malloc(sizeof(int) * n); array = (int *)malloc(sizeof(int) * n); for (i = 0; i < n; i++) { code[i] = 1; maxi[i] = 2; array[i] = i + 1; } while (ALWAYS) { display(code, array, n); copy(code, code + n ,ostream_iterator<int>(cout, " " )); cout << endl; i = n - 1; while (code[i] == maxi[i]) i--; if (i > 0) { code[i]++; for (j = i + 1; j < n; j++) { code[j] = 1; maxi[j] = maxi[i] + ((code[i] == maxi[i]) ? 1 : 0); } } else break; } free(array); free(code); free(maxi); } void display(int *code, int *array, int n) { bool *flag = new bool[n]; if (flag == NULL) return; for (int i = 0; i < n; i++) flag[i] = false; for (int i = 1; i <= n; i++) { int m; for (m = 0; m < n; m++) if (flag[m] == false) break; if (m == n) break; cout << "{"; for (int j = 0; j < n; j++) { if (code[j] == i) { flag[j] = true; cout << array[j]; } } cout << "}"; } cout << endl; delete flag; } void main() { set_partition(3); }