位运算及在算法中的技巧(一)

位运算:

       程序中所有数在计算机内存中都是以二进制的形式存储的,就是直接对整数在内存中的二进制位进行操作,由于直接对内存进行操作,不需要转成十进制,因此处理速度非常快。

常见的小规则:

    1.  & 按位与 (and运算): 两位同时为1才返回1

    一个数&1  结果就是取二进制最末尾。可以判断一个整数的奇偶,二进制末尾为0表示偶数,为1表示奇数。

    2.  | 按位或 (or操作):只要有一位为1即返回1

    常用于二进制特定位上无条件赋值。  一个数 | 1 把二进制最末尾强行变成1。

    3. ^ 按位异或 (xor操作):两位相同返回0,不同返回1。

    最常用性质: a ^ b ^ b = a   应用: 可以进行简单的加密

    4. ~ 取反(not运算):0、 1取反

    5. << 左移(shl运算):a << b  a转2进制后左移b位,后面添加0。

        实际意义: 100 << 2 = 400     a乘以2的b次方,因为在二进制数后添一个0就相当于这个数乘以2。

                    a shi 1 比 a * 2更快,底层中尽量用。

    6. >> 右移(shr运算):a >>b    a除以2的b次方(取整)。

        实际意义:shr 1 来代替 div 2 ,如二分查找,堆插入,求最大公约数的二进制算法用除以2代替mod。会大大提高效率。

 

去掉最后一位101101——10110x >> 1
最后加一个0 x << 1
最后加一个1101101——1011011x << 1 + 1
最后一位变成1 x | 1
最后一位变成0 x | 1 - 1
最后一位取反 x ~ 1
把右边第k位变成1101001——101101 k=3x | (1 << (k-1))
把右边第k位变成0   101101——101001 k =3x & ~(1 << (k-1))
右数第k位取反101001——101101 k=3x ~ (1 << (k-1))
取末三位    101101——101x & 7
取末k位     关键是要找到末尾k个1x & (~(~0 << k))
取右边第k位 x & (1 << ( k-1))
把末k位变成1 找到末尾的1,然后或一下x  | ((1<<k) -1 )

       练习不在多,而抓住本质就好。

如思路最后两道:

    取末k位:那么首先就可以知道末k为都1,其余位0的然后与一下就可以了。那么怎么取末k为1,其它为0, 全是1的相左走k位,然后取反就得到了。

    把末k位变成1:找到末k位为1,其它为0的然后或一下

实战:
取二进制从右到左的p位置,面向右数n个二进制位。
  如 1637,二进制为11001100101,这里p7n5输出为11001
public static void main(String[] args) {
        System.out.println(Integer.toBinaryString(1637));
        int i = 1637, p = 7, n = 5;
        // 去掉不要的右边几位
        i = i >> (p - n);
        //  取右边n位
        i = i & ~(~0 << n);
        System.out.println(Integer.toBinaryString(i));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值