子集生成

//子集生成
#include "stdio.h"


int num[] = {1,2,3,4};
/**增量构造法**/
/**
 *A中的元素的个数是不确定的,每次递归都要输出。
 *注意:下面代码使用了定序的小技巧:规定集合中的所有元素的编号从小到大排序。
 *
 */
void print_subset (int n,int *A,int cur) {
	int i,s;
	for (i = 0;i < cur;i++) {
		printf ("%d ",num[A[i]]);
	}
	printf ("\n");
	s = cur ? A[cur-1] + 1:0;
	for (i = s;i < n;i++) {
		A[cur] = i;
		print_subset (n,A,cur+1);
	}
}	


/**位向量法**/
/**
 *构造一个位向量B,当B[i] = 1时,表示num[i]在子集中。
 *必须当“所有的元素”全部确定完毕后才是一个完整的子集,因此是if(cur >= n)成立时才输出。 
 */
void print_subset2 (int n,int *B,int cur) {
	if (cur >= n) {
		int i;
		for (i = 0;i < n;i++) {
			if (B[i]) {
				printf ("%d ",num[i]);
			}
		}
		printf ("\n");
		return;
	}
	B[cur] = 1;
	print_subset2 (n,B,cur+1);
	B[cur] = 0;
	print_subset2 (n,B,cur+1);
}
int main () {

	int A[20];
	print_subset (4,A,0);
	printf ("---hr---\n");
	print_subset2 (4,A,0);
	return 0;
}

 

//二进制法

// 比如一个数字10,二进制为1010,就表示num[1],num[3]在子集中。
#include "stdio.h"


int num[] = {1,2,3,4};
void print_subset3 (int n,int s) {
	int i;
	for (i = 0;i < n;i++) {
		if (s & (1 << i)) {//s & (1 << i)可以确定s的二进制第i位是否为1(第一位为0)
			printf ("%d ",num[i]);
		}
	}
	printf ("\n");
}


int main () {
	int i;
	int n = 4;
	for (i = 0;i < (1 << n);i++) {
		print_subset3 (n,i);
	}
	return 0;
}



 

你可能感兴趣的:(穷举)