列出全部的子集

算法要求

編寫一個程序,列出{1,2,3,…,n}這個集合的全部子集,包括空集合。git

列出一個集合的全部子集有不少作法,題目中並無要求依某個特定的次序來排列, 所以是不難作出來的。算法

由於集合中一共有n個元素,因此總共就會有2^n子集;例如{1,2,3}有以下子集:數組

{}this

{1} {2} {3}spa

{1,2} {1,3} {2,3}code

{1,2,3}字符串

分析

看到2^n,就想起了二進制數,能夠使用二進制的第 i 位表示是否包含集合的第 i 個元素,如數字6的二進制形式是110,表示取集合的第2,3兩個元素組成的子集。這樣0~2^n -1的數字就能夠表示所有子集,每個數字表明一個子集,實現應該不難。get

算法實現

#include  <stdio.h>
#include  <stdlib.h>

#define   MAXSIZE   20
#define   LOOP       1

int main(void)
{
	char digit[MAXSIZE];
	int  i, j;
	int  n;
	char line[100];

	printf("\nDirect Generation of All Subsets of a Set");
	printf("\n=========================================");
	printf("\n\nNumber of Elements in the Given Set --> ");
	gets(line);
	n = atoi(line);/*把字符串轉換成整型數據*/

	/* ---You'd better check to see if n is too large--- */

	for (i = 0; i < n; i++)  /* clear all digits to 0,能夠認爲是初始化,注意digit是字符數組 */
		digit[i] = '0';

	printf("\n{}");          /* outpout empty set {} ,空集是全部集合的子集   */
	while (LOOP) {
		for (i = 0; i < n && digit[i] == '1'; digit[i] = '0', i++)
			;              /* find first 0 position  找到第一次出現0的位置,或者設置它爲0  */
		if (i == n)         /* if none, all pos. are 1  */
			break;         /* thus all elem. are in set,這是在遍歷完全部的元素以後,結束循環*/
		else
			digit[i] = '1';/* now add one to this pos,設置該位置的元素爲1  */

		for (i = 0; i < n && digit[i] == '0'; i++)
			;              /* find first 1 position 找到第一次出現1的位置   */
		printf("\n{%d", i + 1);  /* show its numner and   */
		for (j = i + 1; j < n; j++) /* others,遍歷後面的元素,找到標記爲1的位置,打印出來該位置對應的數*/
			if (digit[j] == '1')
				printf(",%d", j + 1);
		printf("}");
	}
	return 0;
}

實驗結果

當輸入n=2的狀況下,編譯運行subset.c,實驗結果以下:
it

相關文章
相關標籤/搜索