找到大多数相应的位

时间:2016-08-29 18:04:47

标签: bit-manipulation bit bitset

我试图找到一种有效的方法来获得一组相同大小的整数中的大部分相应位。例如,在给定的整数中:

12 => 1 1 0 0
9  => 1 0 0 1
9  => 1 0 0 1
3  => 0 0 1 1

大部分位(列式)可表示为:

      1 0 0 1 

如果1和#0的数量相等(列方式),则应为1.我希望使用整数来实现这一点,如果可能的话,不将整数转换为二进制字符串。

1 个答案:

答案 0 :(得分:1)

在C中,这可能是这样的:

unsigned arr[] = { 12, 9, 9, 3 };     //  values to loop through
unsigned len = sizeof(arr) / sizeof(arr[0]);   //  # of values
unsigned result = 0;                  //  collect result here
unsigned bits = sizeof(arr[0]) * 8;   //  number of bits to consider
unsigned threshold = len / 2 + ((len & 1) ? 1 : 0);  //  minimum # of 1 to get a 1
unsigned bit = 1 << (bits - 1);       //  bit mask; point to most significant bit position

for (unsigned pos = 0; pos < bits; pos++) {
    unsigned ones = 0;
    for (unsigned i = 0; i < len; i++) {
        if ((bit & arr[i]) != 0) {
            ones++;
        }
    }

    result = (result << 1) + ((ones >= threshold) ? 1 : 0);
    bit = bit >> 1;
}

printf("\n%d\n", result);

外部循环将位掩码从最重要的一端移动到最不重要的一端。内部循环对设置为1的位进行计数。如果1位超过阈值,则将1移入结果。否则,移入0。最后,结果保持所请求的多数位。

这可以进一步优化,但不是为了保持可读性。

针对特殊情况len == 4

简化
unsigned arr[] = { 12, 9, 9, 3 };     //  values to loop through
unsigned len = sizeof(arr) / sizeof(arr[0]);   //  # of values
unsigned result = 0;                  //  collect result here

//  for len==4, majority means that 2 or more bits are 1
for (unsigned i = 0; i < len - 1; i++)
    for (unsigned j = i + 1; j < len; j++) {
        result = result | (arr[i] & arr[j]);
    }

printf("\n%d\n", result);