运用二进制生成集合的所有子集

感谢刘大大;


#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
void print_subset(int n,int s){
	for(int i=0;i<n;i++)
	  if(s&(1<<i)) printf("%d",i);
	cout<<endl;  
}
int main(){
	int s[4]={0,1,2,3};
	for(int i=0;i<(1<<4);i++)
	  print_subset(4,i);
	return 0;
}

我要解释一下:

所谓用二进制表示数就是用二进制的每一个数位表示一个数,当然 1 表示有一个数 0表示没有。

比如 一个二进制数 01111,我们可以用来表示一个集合p[4]={0,1,2,3},从右到左一次是0,1,2,3,4.

转化为10进制就是2的n次方-1;

对于主函数中的for循环中(1<<4),我开始在想为什么不是直接i<4就好,4个数4个循环嘛。发现不是这样的,

这样做只是把00000,00001,00010,00011,00100,忘了先决条件,用0,1代表是否含有这数字。最重要的一点就是

01111仅仅是代表这个集合最大的子集罢了。


然后就是subset函数了,这里面的操作是把二进制转化为十进制的数字。(真的,算法真的好奇妙啊!)



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值