二进制计算笔记

位运算 \red{\huge{位运算}} 位运算

①. n n n的二进制位第 k k k位是什么?

此处的第 k k k位是从 1 1 1开始的,但是二进制的位数是从 0 0 0开始的,也就是说 0 0 0位是第 1 1 1位。

解决这个问题需要两个步骤:

  1. 把第 k k k位移动到最后一位:
    n > > k − 1 n>>k - 1 n>>k1
  2. 看个位的数字是什么:
    x   &   1 x\space \& \space 1 x & 1

1.2步骤综合:
n   > >   ( k − 1 )   &   1 n \space >> \space (k - 1) \space \& \space 1 n >> (k1) & 1

代码实现

#include <iostream>

using namespace std;

int main ()
{
    int n;
    cin >> n;
    
    int k;
    cin >> k;
    
    cout << n >> (k - 1) & 1 << endl;
    
    return 0;
}

②. n n n的二进制表示之中有多少个 1 1 1

要解决这个问题首先先看一个知识点: l o w b i t lowbit lowbit

l o w b i t lowbit lowbit操作

定义 o r or or作用

用来求解一个二进制数从低位到高位,第一个 1 1 1形成的二进制数。
例如 1001000 1001000 1001000,进行 l o w b i t lowbit lowbit操作之后,返回的结果是 1000 1000 1000(返回的结果也是一个二进制数)。

核心操作及其推理
核心操作:

x   &   − x   =   x   &   ( − x   +   1 ) x\space \& \space -x \space = \space x \space \& \space (-x \space + \space 1) x & x = x & (x + 1)

推理:

假定有:
x = 1010..... ( 1 ) 000 x = 1010..... (1)000 x=1010.....(1)000
− x = 0101..... ( 0 ) 111 -x = 0101.....(0)111 x=0101.....(0)111
− x + 1 = 0101..... ( 1 ) 000 -x + 1 = 0101.....(1)000 x+1=0101.....(1)000
x & ( − x + 1 ) = 0000..... ( 1 ) 000 x \& (-x + 1) = 0000.....(1)000 x&(x+1)=0000.....(1)000
观察可以知道
x   &   − x   =   x   &   ( − x   +   1 ) x\space \& \space -x \space = \space x \space \& \space (-x \space + \space 1) x & x = x & (x + 1)
得证,说明了 x & − x x\&-x x&x就可直接返回一个数二进制数第一位 1 1 1和低位构成的二进制数。

原问题处理

有了 l o w b i t lowbit lowbit操作之后,可以开始对原问题进行求解。

思路

对于原数,每次都用 l o w b i t lowbit lowbit操作减去最小位 1 1 1对应的二进制数,并记录次数,直到原数减成 0 0 0为止。

代码实现
#include <iostream>

using namespace std;

int lowbit(int x)
{
    return x & -x;
}

int main ()
{
    int n;
    cin >> n;
    
    while(n--)
    {
        int x;
        cin >> x;
        
        int res = 0;
        while(x)
        {
            x -= lowbit(x);
            res++;
        }
        
        cout << res << ' ';
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值