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; }
时间: 2024-10-19 20:14:48