用蛮力法(穷举法)求解幂集问题

用蛮力法(穷举法)求解幂集问题

【问题描述】对于给定的正整数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}),属于指数级的算法。


 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值