//把右起第一个0变成1 | (100101111->100111111) | x or (x+1)
//把右边连续的0变成1 | (11011000->11011111) | x or (x-1)
//取右边连续的1 | (100101111->1111) | (x xor (x+1)) shr 1
//取右起的第一个1 | (100101000->1000) | x and (-x)
#include <cstdio>
#include <cstring>
#include <algorithm>
/*A:x &= x-1;*/
//usage1:
bool is_pow2(int x) //判断x是否2的n次方,x>0,x=1,2,4,……8 return 1;
{
x&=x-1;return (x==0);
}
//usage2:
int count1(int x)//计算数number的二进制中包含1的个数,x>0
{
int co=0;
while(x)
{
co++;
x&=x-1;
}
return co;
}
//usage3:
void enumerate_subset(int x) //x>=0
{
int y=x;
do{
//printf("%d\n",y);
y=(y-1)&x;
}while (y!=x); //处理完0后,会有-1&x=x;
}
/* */
/*B:枚举x的所有大小为k的子集*/
void enumerate_subset_ofsize_k(int k,int n)
{
int cc=(1<<k)-1,tot=1<<n;
while (cc<tot)
{ //printf("%d\n",cc);
int x=cc&(-cc),y=cc+x;
cc=((cc&(~y))/x>>1)|y;
}
}
/*C:枚举不含相邻元素的集合*/
void enumerate_subset_of_noconsecutive(int n)
{
int tot=1<<n,t;
for (int i=0;;)
{ //printf("%d\n",i);
t=i|(i>>1);
t=tot-1-t;
t=t&(-t);
if (t==0)break;
i=(i+t)&(tot-t);
}
}
##位运算若干应用##
最新推荐文章于 2015-04-15 17:15:35 发布