用蠻力法(窮舉法)求解冪集問題

解語花_99發表於2020-10-05

用蠻力法(窮舉法)求解冪集問題

【問題描述】對於給定的正整數n(n>=1),求1~n構成的集合的冪集(即由1~n的集合中所有子集構成的集合,包括全集和空集)

直接窮舉法

       設集合a[0..2]={1.2.3},其所有集合元素對應的二進位制位及其十進位制數如表所示。

      集合元素   對應的二進位制位      對應的十進位制數
           {}             000                  0
          {1}             100                  4
          {2}             010                   2
         {1,2}             110                   6
          {3}             001                    1
        {1,3}             101                    5
        {2,3}             011                    3
       {1,2,3}            111                    7

    其實就是輸出{1,2,3}在0~7所表示的二進位制的所在的1的位置。

源程式如下:

#include <iostream>
using namespace std;

//二進位制數變化
void inc(int b[],int n) {
	for (int i = 0; i < n;i++) {
		if (b[i]) {                //將元素1改為0
			b[i] = 0;
		}
		else {                     //將元素0改為1並退出for迴圈
			b[i] = 1;
			break;
		}

	}

}

//求冪集
void PSet(int a[],int b[],int n) {    
	int i, k;
	int pw = (int)pow(2, n);       //求2的n次方
	cout << "1~"<<n<<"的冪集為:" << endl;

	for ( i = 0; i < pw;i++) {
		cout << "{";
		for (k = 0; k < n;k++) {
			if (b[k]) {                      //輸出二進位制位中為1的所對應的{1,2,3..n}所在的位置的數
				cout <<" "<< a[k];
			}
		}
		cout << "}";
		inc(b, n);                //變更二進位制數
	}
	cout << endl;

}

int main() {
	int n = 0;
	cout << "請輸入n的數" << endl;
	cin >> n;
	int *a=new int [n];      //用陣列a表示1-n的十進位制數
	int *b = new int[n];      //用陣列b表示二進位制位
	for (int i = 0; i < n;i++) {
		a[i] = i + 1;          //a初始化為1,2,3..n
		b[i] = 0;               //b初始化為{0,0,0..}
	}
	PSet(a,b,n);

	system("pause");
	return 0;
}

輸出結果為:

請輸入n的數
5
1~5的冪集為:
{}{ 1}{ 2}{ 1 2}{ 3}{ 1 3}{ 2 3}{ 1 2 3}{ 4}{ 1 4}{ 2 4}{ 1 2 4}{ 3 4}{ 1 3 4}{ 2 3 4}{ 1 2 3 4}{ 5}{ 1 5}{ 2 5}{ 1 2 5}{ 3 5}{ 1 3 5}{ 2 3 5}{ 1 2 3 5}{ 4 5}{ 1 4 5}{ 2 4 5}{ 1 2 4 5}{ 3 4 5}{ 1 3 4 5}{ 2 3 4 5}{ 1 2 3 4 5}
請按任意鍵繼續. . .

【演算法分析】

        演算法中pw迴圈2^{n}次,不考慮冪集輸出,inc()的時間複雜度為O(n),所以演算法的時間複雜度為O(n*2^{n}),屬於指數級的演算法。


 

相關文章