【位运算符与逻辑运算符知识点】【二进制枚举子集】【just for 状压】

(1):按位运算符&:例如:0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1 即同为 1 的位,结果为 1,否则结果为 0。

(2)按位或运算符|:例如:0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1即只要有1个是1的位,结果为1,否则为0。

(3)按位异或运算符^:例如:0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0 即相应位的值相同的,结果为 0,不相同的结果为 1。

(4)按位取反运算符~:用来求一个位串信息按位的反,即哪些为0的位,结果是1,而哪些为1的位,结果是0。

(4)左移运算符:

规则:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零(左移一位相当于乘2)。

计算方法:例如:8 << n的值为8*(2^n)

(5)右移运算符:

规则:按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1(右移一位相当于除2)。

计算方法:例如:8 >> n的值为 8/(2^n)  ,这里是取商哈,不要余数。

巧用:

可利用右移运算符计算a的第b个二进制位是什么:(a>>b)&1。

二进制枚举子集:

#include<stdio.h>
int k[5] = {1,2,3,4,5};
//二进制枚举子集:n个数有2^n个子集,对应一共有2^n个二进制数。 
//每个二进制数的位权(0||1)对应原集合中的数是否存在于该子集 ,0为不存在,1为存在 
void print(int s,int n)
{
    int i;
    for(i = 0; i < s; i ++)
        if(s&(1<<i))
            printf("%d ",k[i]);
    //比如s = 7  ->二进制数为:00111 
    //当i = 0,1,2时才输出s=7中的数 
    //s&(1<<0) == 7&1 == 00111&1 == 1 输出 k[0]=1
    //s&(1<<1) == 7&2 == 00111&10 == 1 输出 k[1]=2
    //s&(1<<2) == 7&4 == 00111&100 == 1输出 k[2] = 3    
    printf("\n");
    return;
}
int main()
{
    int i,n = 5;
    for(i = 0; i < (1<<n); i ++)//(1<<n)等价于1*2^n 
    {
        print(i,n);
    }    
    return 0;
}


参考资料:

https://baike.baidu.com/item/%E8%BF%90%E7%AE%97%E7%AC%A6/7752795

http://blog.sina.com.cn/s/blog_4e345ce70100u5pr.html

http://blog.csdn.net/liangzhaoyang1/article/details/52853207


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值