MENU

二进制中1的个数

• June 4, 2021 • Read: 1514 • 算法,学习笔记,算法&题库

给定一个长度为 $n$ 的序列,请你求出数列中每个数的二进制表示中 $\rm{1}$ 的个数。

输入格式

第一行包含整数 $n$。
第二行包含 $n$ 个整数,表示整个数列。

输出格式

共一行,包含 $n$ 个整数,其中的第 $i$ 个数表示数列中的第 $i$ 个数的二进制表示中 $\rm{1}$ 的个数。

数据范围

${\rm{1}} \le {\rm{n}} \le {\rm{100000}}$
${\rm{0}} \le {\rm{数列中元素的值}} \le {\rm{10^9}}$

输入样例

5
1 2 3 4 5

输出样例

1 1 2 1 2

题解

(lowbit)

$(\rm{x}\&\rm{-x})\Longleftrightarrow(\rm{x}\&(\sim\rm{x+1}))$
例如二进制 $\rm{1010101000}$ 经过 $\sim$ 运算后为 $\rm{0101010111}$,$+1$ 后为$\rm{0101011000}$,故 $\rm{x}\&(\sim\rm{x+1}))$ 将最后一个 $\rm{1}$ 之前的所有数都与为 $\rm{0}$,即 $\begin{bmatrix} 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 & 0 & 0\end{bmatrix}$ 或运算后得到 $\rm{0000001000}$。

基础拓展:

以 $\rm{x}=\rm{000}\cdots\rm{01010}$ 为例:
源码($x$):$\rm{000}\cdots\rm{01010}$
反码($\sim x$):$\rm{111}\cdots\rm{10101}$
补码($\sim x+\rm{1}$):$\rm{111}\cdots\rm{10110}$

计算机中使用补码来存储负数。

C++ 代码

#include <iostream>

using namespace std;

int lowbit(int x)
{
    return x & -x;//x & (~x + 1)
}

int main()
{
    int n;
    cin >> n;
    while(n--)
    {
        int x, res = 0;
        cin >> x;
        while(x)
            x -= lowbit(x), res++;    //每次减去x的最后一位1
        cout << res << " ";
    }
    return 0;
}
版权属于:字节星球/肥柴之家 (转载请联系作者授权)
原文链接:https://www.bytecho.net/archives/1782.html
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

Last Modified: August 29, 2023
Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment