您的位置:首页 > 其它

二进制法生成子集

2017-11-29 13:27 190 查看
由于位运算是最快的运算,于是就出现了二进制优化这种玩意儿。

一个二进制数只有0或者1,所以我们可以将一个二进制数看做一个bool数组。

此时二进制数大叫道:lz一个人就是一支军队,魔哈哈哈……

。。。

为了学好高端大气上档次的数据结构,我决定要坚实基础,先把这种运算、这道题渗透:

好吧,其实就是输出一个字符串的子串罢了。

输入:第一行有一个整数len代表字符串的长度

第二行给出一个长度为len的字符串

输出:这个字符串的所有子串

自编样例:

Input:

4
abcd


Output:

a
b
ab
c
ac
bc
abc
d
ad
bd
abd
cd
acd
bcd
abcd


注意输出的第一行其实是一个空集…

思:

在选择的时候,因为字符串中的每一个字符都有两种选择:选or不选

所以可以用1来代表选,0来代表不选

先用b来代表枚举的范围,如样例中的b=2^4-1=15(十进制)=1111(二进制)

那么用i从0000(0)到1111(15)枚举,就可以挨个找到其中的每一种情况(非排序)

这时比较麻烦的是j的那个循环,再次以样例为例:

注:与运算“&”比较两个二进制数的每一位,如果都为1则在结果的同一位置返回1,否则返回0

假设i的二进制是1011

1. j=0 那么 1011 & 0001=0001>0 第0位被选择了=>输出A[0]

2. j=1 那么 1011 & 0010=0010>0 第1位被选择了=>输出A[1]

3. j=2 那么 1011 & 0100=0000==0 第2位没有选 =>不输出A[2]

4. j=3 那么 1011 & 1000=1000>0 第3位被选择了=>输出A[3]

输出结果:abd

没错就是这样

/*二进制法输出子集*/
#include<cstdio>
#define MAXN 10
int len;
char A[MAXN+5];
int main(){
scanf("%d",&len);
scanf("%s",A);
int b=(1<<len)-1;
for(int i=0;i<=b;i++){
for(int j=0;j<=len-1;j++)
if(i&(1<<j))
printf("%c",A[j]);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: