1.增量构造法
思路:
开始时没有元素,一次加一个元素并且输出;
注意:
1).注意一种写法:s = cur ? A [cur - 1] + 1 : 0,不必用if-else结构;
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
void print_subset ( int n , int *A , int cur ) {
for ( int i = 0 ; i < cur ; i ++ ) printf("%d",A[i]) ;
printf("\n") ;
int s = cur ? A[cur - 1] + 1 : 0 ;
for ( int i = s ; i < n ; i ++ ) {
A[cur] = i ;
print_subset ( n , A , cur + 1 ) ;
}
}
int main() {
int n ;
while ( scanf("%d",&n) == 1 ) {
int A[n] ;
print_subset ( n , A , 0 ) ;
}
return 0 ;
}
2.位向量法
思路:
每个数都选一遍,构造一个内容为0或1的位向量数组,第cur个数的位向量为0则不选,为1则选;
注意:
1). “ return;” 的用法:
第一层至第n层选第一种情况,return选第n层的第二种情况(假设只有两种情况);再return选第n-1层的第二种情况,顺序着选第n层的两种情况;再return选第n-2层的第二种情况,顺序选后面两层的情况;( return的作用是每次选到底时跳回来)
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
void print_subset ( int n , int *A , int cur ) {
if ( cur == n ) {
for ( int i = 0 ; i < n ; i ++ )
if ( A[i] != 0 ) printf("%d",i) ;
printf("\n") ;
return ;
}
A[cur] = 0 ;
print_subset ( n , A , cur + 1 ) ;
A[cur] = 1 ;
print_subset ( n , A , cur + 1 ) ;
}
int main() {
int n ;
while ( scanf("%d",&n) == 1 ) {
int A[n] ;
print_subset ( n , A , 0 ) ;
}
return 0 ;
}
3.二进制法
思路:
把每个子集用一串二进制数来表示,0代表无此数,1代表有此数。利用二进制的&进行输出;
注意:
1).如何输出:利用 ( 1 << j ) & i 判断有没有 j 对应的数字;
2)." << " : 左移符号,1<<2 结果是100,1<<n 十进制是乘2的n次方;
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
int main() {
int n ;
while ( scanf("%d",&n) == 1 ) {
for ( int i = 0 ; i < ( 1 << n ) ; i ++ ) {
for ( int j = 0 ; j < n ; j ++ ) {
if ( ( 1 << j ) & i ) printf ("%d",j) ;
}
printf("\n") ;
}
}
return 0 ;
}