编程填空题:麻烦的位运算

本文介绍了如何使用位运算符(如按位与、按位取反)找出给定整数n二进制表示中第一个0的左侧全1部分的算法,并通过示例解释了((n+1)&(~n))-1这一表达式的逻辑。同时提及了一个与之相关的编程问题UVA1354VirtualJudge,涉及二进制枚举子集的应用。
摘要由CSDN通过智能技术生成

闲着没事干可以做做

可以看到,那个函数直接return了,也就是说,得找到一个表达式,直接求出结果

简单分析一下:

其第i位为1当且仅当n的右边i位均为1

也就是说,前i-1位有0,第i位就是0

也就是说,找到n的第一个出现的0的位置,返回这个位置前面都为1的数字就可以了

先给出答案:

((n + 1) & (~n)) - 1

完整的代码看一下:

#include <iostream>
using namespace std;

int bitManipulation4(int n) {
  return
    ((n + 1) & (~n)) - 1
;
}

int main() {
    int t, n;
    cin >> t;
    while (t--) {
        cin >> n;
        cout << bitManipulation4(n) << endl;
    }
    return 0;
}

先复习一下按位运算符在集合中的意义吧

设二进制集合A和B

运算符及意义:

与(&)运算符:A&B 计算出A和B的并集

或(|)运算符:A|B 计算出A和B的交集

按位取反(~)运算符:~A 计算出A的补集

异或(^)运算符:A^B 计算出A与B的对称差集

((n + 1) & (~n))

这个就是用来找到找到n的第一个出现的0的位置,并且只有该位置为1的数

减1就是结果

用例子来讲讲:

假设n的二进制为:1011

n + 1 = 1100

~n = 0100

((n + 1) & (~n)) = 0100

((n + 1) & (~n)) - 1 = 0011

二进制的运算在其他地方也可以用到,比如枚举子集

推荐一题:

Mobile Computing - UVA 1354 - Virtual Judge (vjudge.net)

可以用枚举子集的方法从上到下构建二叉树

这题实际上是我上篇博客的主题,但是那篇博客不是用枚举子集的方法来做的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值