您的位置:首页 > 其它

子集生成

2017-03-25 21:45 274 查看
n 个数的子集,每个数都有两种状态:选或不选,所以共有 2^n 种情况;

子集生成有几种不同情况:

第一种是给定 n,生成 1-n 的所有子集;

第二种是给定集合,生成该集合的所有子集;

下面几种方法都是不重复集;

1 到 n 的子集

增量构造法:

先列举 3 的子集,找规律,再写程序;



1

1 2

1 2 3

1 3

2

2 3

3

// 增量构造法
#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 10000;
int arr[maxn];

void sub_set(int *a, int n, int cur)
{
for(int i = 1; i < cur; i++) printf("%d ", a[i]);
printf("\n");
for(int i = (cur==1) ? 1 : arr[cur-1]+1; i <= n; i++)
{
arr[cur] = i;
sub_set(a, n, cur+1);
}
}

int main()
{
sub_set(arr, 4, 1);
return 0;
}


行向量法:

数组保存每个数选中还是不选;

1 2 3

1 2 []

1 [] 3

1 [] []

[] 2 3

[] 2 []

[] [] 3

[] [] []

// 行向量法
void sub_set1(int *b, int n, int cur)
{
if(cur > n)
{
for(int i = 1; i <= n; i++)
if(b[i]) printf("%d ", i);
printf("\n");
return ;
}
b[cur] = 1;
sub_set1(b, n, cur+1);
b[cur] = 0;
sub_set1(b, n, cur+1);
}


二进制法:

#include <iostream>
#include <cstdio>

using namespace std;

void sub_set(int n, int s)
{
for(int i = 0; i < n; i++)
if(s &(1 << i)) printf("%d ", i);
printf("\n");
}

int main()
{
for(int i = 1; i < (1 << 3); i++)
{
sub_set(3, i);
}
return 0;
}


给定集合的子集

增量构造法:

如 {1, 3, 5}:



1

1 3

1 3 5

1 5

3

3 5

5

// 增量构造法
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 10000;
int arr[maxn];

// 仅适用于集合非负,当然可以根据集合重新memset一下
void sub_set(int *a, int *b, int n, int cur)
{
for(int i = 1; i < cur; i++) printf("%d ", a[i]);
printf("\n");
for(int i = cur; (a[cur-1] != b[n-1]) && i <= n; i++)
{
// 不设置这一步会出现 3 3 的情况,因为后面一个3没有和前面的3一样同步i
while(b[i-1] == a[cur-1]) i++;
a[cur] = b[i-1];
sub_set(a, b, n, cur+1);
}
}

int main()
{
memset(arr, -1, sizeof arr);
int b[] = {0, 1, 3};
sub_set(arr, b, 3, 1);
return 0;
}


行向量法:

1 3 5

1 3 []

1 [] 5

1 [] []

[] 3 5

[] 3 []

[] [] 5

[] [] []

// 行向量法
void sub_set1(int *a, int *b, int n, int cur)
{
if(cur > n)
{
for(int i = 1; i <= n; i++)
if(b[i]) printf("%d ", a[i-1]);
printf("\n");
return ;
}
b[cur] = 1;
sub_set1(a, b, n, cur+1);
b[cur] = 0;
sub_set1(a, b, n, cur+1);
}

int main()
{
int b[4];
int a[] = {1,2,3};
sub_set1(a, b, 3, 1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: