二进制两个连续的1位

时间:2019-03-08 05:50:25

标签: c

我正在尝试用C实现,该C以整数形式输出两个连续的1位的数目而不重叠。这是我的代码:

#include <stdio.h>

int numPairs(int num) {
    int count = 0;
    while (num) {
        num = (num & (num << 1));
        count++;
    }
    return count / 2;
}

int main(){
    printf("%d\t", numPairs(10000));
    printf("%d\t", numPairs(146));
    printf("%d\t", numPairs(7645));
    printf("%d\t", numPairs(16383));
    return 0;
}

我的输出是1 0 1 7

但输出应为1 0 3 7

7645外,其他所有内容都是正确的,我不知道这有什么问题。

对于7645,我的代码给出的结果为1,但正确的结果为3

2 个答案:

答案 0 :(得分:2)

您的方法不合适:

您计算使表达式n = n & (n << 1);为空所需的迭代次数。这将是连续1位的最大数量。如果这些位对是分开的,则结果将与不重叠的位对的数量不同。

在十进制76450x1ddd0001 1101 1101 1101中,有3组3个连续的1位,但是它们在循环的3次并行迭代中为空,因此count / 21

您必须使用其他算法,例如:

int numPairs(int num) {
    int count = 0;
    unsigned int x = num;
    while (x) {
        if ((x & 3) == 3) {
            count++;
            x >>= 2;
        } else {
            x >>= 1;
        }
    }
    return count;
}

答案 1 :(得分:0)

如果速度很重要,也可以使用位操作来完成:

int numPairs(uint32_t x) {
    return __builtin_popcount((((x ^ 0x55555555) + 0x55555555) ^ 0x55555555) & x);
}

这会在每个不相交的2位一组的高位产生1位,然后对这1位进行计数。