7.3.1增量構造法
思路:一次選出一個元素放到集合中。自己對于遞歸的了解還是不夠,這裡雖然沒有明确給出遞歸停止條件,但是如果無法繼續添加元素,就不會再繼續遞歸,然後就是我頭疼的回溯啦。
#include<stdio.h>
int num[4],n;
void A(int n,int *a,int ans)
{
for(int i = 0; i < ans; i ++)//列印目前元素
printf("%d ",a[i]);
printf("\n");
int s = ans?a[ans-1]+1:0;//确定目前元素的最小可能值
for(int i = s; i < n; i ++)
{
a[ans] = i;
A(n,a,ans+1);//遞歸構造子集
}
return;
}
int main()
{
n = 3;
A(n,num,0);
return 0;
}
7.3.2位向量法
思路:構造一個位向量a[i],如果a[i]=1,當且僅當i在集合子集a中。
#include<stdio.h>
int num[4],n;
void print_subset(int n,int *a,int ans)
{
if(ans == n)
{
for(int i = 0; i < ans; i ++)//列印目前集合
if(a[i])
printf("%d ",i);
printf("\n");
return;
}
a[ans] = 1;//選擇第cur個元素
print_subset(n,a,ans+1);
a[ans] = 0;//不選第cur個元素
print_subset(n,a,ans+1);
return;
}
int main()
{
n = 3;
print_subset(n,num,0);
return 0;
}
7.3.3二進制法
#include<stdio.h>
int n = 3;
void print_subset(int n,int ans)
{
for(int i = 0; i < n; i ++)//列印{0,1,2,3..n-1}的子集ans
if(ans&(1<<i))
printf("%d ",i);
printf("\n");
return;
}
int main()
{
for(int i = 0; i < (1<<n); i ++)//枚舉各子集對應的編碼
print_subset(n,i);
return 0;
}