1. 程式人生 > >C語言實現陣列所有子集

C語言實現陣列所有子集

這段程式碼與之前釋出的01揹包問題密切相關。在使用暴力法解決01揹包問題的時候,最大的問題在於求出一個數組的所有子集,並在這些子集中搜索出最優解。也曾經在網上搜索了大家關於求子集的問題的答案,深受啟發,所以在這裡把程式碼貼出來,以供後來者參考。程式碼沒有經過太多的優化,可能看起來比較Ugly。

#include <stdio.h>

//k是開始字元的位置,n是陣列的長度,l是子集的位數
void subArray(int A[], int k,int l, int n);

//初始化整個子集陣列
void initArray(int n);

//用於輸出子集的陣列
int priArray[4];
void printArray(int n);

int counter = 0;

int main()
{
	int i;
	
	int array[4] = {1, 2 , 3, 4};
    
    //0是所有陣列的子集
    printf("0\n");
    counter += 1;
	
	for (i = 0; i < 4; i++)
	{
        initArray(4);
		//遞迴演算法需要保證從第一個元素開始的所有的元素都被遍歷到
		priArray[0] = array[i];
        counter += 1;
		printArray(1);
		subArray(array, i+1, 2, 4);	
	}
    
    printf("\nThe SubArray is %d\n", counter);
    
	return 0;
}

/*
 * 該遞迴演算法每次只向後尋找一位數字。
 * 例如k=1時,只會尋找2,3,4;k=2時,只會尋找3,4
 */

void subArray(int A[], int k, int l, int n)
{
	int i;
	
	if (k == n-1)
	{
        //n是整個陣列的長度,k是整個子集的上一位字元,當k == n-1時,意味著已經是最後一個了。
        priArray[l-1] = A[k];
        counter += 1;
		printArray(l);
	}
	else
	{
		for ( i= k; i <= n-1; ++i)
		{
			priArray[l-1] = A[i];
            counter += 1;
			printArray(l);
			subArray(A, i+1, l+1,n);
		}
	}
	
}

/*
 * 列印子集陣列的函式
 */

void printArray(int n)
{
	int i;
	
	for (i = 0; i < n; i++)
	{
		printf("%d	", priArray[i]);
	}
	printf("\n");
}

void initArray(int n)
{
    for (int i = 0; i<= n-1 ; i++) {
        priArray[i] = 0;
    }
}

ps:用vc運行了一下,結果如圖,