算不了。按位数(位置)的32位二进制数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算不了。按位数(位置)的32位二进制数组相关的知识,希望对你有一定的参考价值。

给出了32位二进制数的array(10^5 size),我们需要计算no。这些数字的每一点都有。

例如:

Array :  {10101,1011,1010,1}  
Counts : {1's place: 3, 2's place: 2, 3's place: 1, 4's place: 2, 5's place: 1}  

没有比特操纵技术似乎满足了我的限制。

答案

好吧,这应该可以通过两个循环来解决:一个遍历数组,另一个掩盖正确的位。运行时间对于你的约束来说应该不会太糟糕。

这是一个生锈实现(从我的头脑中,没有经过充分的测试):

fn main() {

    let mut v = vec!();

    for i in 1..50*1000 {
        v.push(i);
    }

    let r = bitcount_arr(v);

    r.iter().enumerate().for_each( |(i,x)| print!("index {}:{} ",i+1,x));


}


fn bitcount_arr(input:Vec<u32>) -> [u32;32] {

    let mut res = [0;32];

    for num in input {

        for i in 0..31 {
            let mask = 1 << i;

            if num & mask != 0 {
                res[i] += 1;        
            }
        }

    }
    res
}
另一答案

这可以通过转置加法来完成,尽管阵列有点长。

要转置加法,请使用计数器数组,但不是为每个位置使用一个计数器,我们将为计数的每个位使用一个计数器。因此,一个计数器跟踪每个位置是否计数是偶数/奇数,一个计数器跟踪每个位置是否计数中有一个2,等等。

要在此添加数组元素,只需要半加操作(&查找新进位,^更新),因为它只是一个条件增量:(未测试)

uint32_t counters[17];
for (uint32_t elem : array) {
    uint32_t c = elem;
    for (int i = 0; i < 17; i++) {
        uint32_t nextcarry = counters[i] & c;
        counters[i] ^= c;
        c = nextcarry;
    }
}

我选择了17个计数器因为log2(10^5)小于17.所以即使所有位都是1,计数器也不会换行。

要读取位k的结果,请取每个计数器的k位。

使用一些完全添加和重复的计数器,可以使用稍微更有效的方法将数组的多个元素一次添加到计数器中。

以上是关于算不了。按位数(位置)的32位二进制数组的主要内容,如果未能解决你的问题,请参考以下文章

压位高精

环形链表(哈希表链表)寻找两个正序数组的中位数(数组二分查找)二进制求和(位运算数学)

华为OD机试真题Java实现整型数组按个位值排序真题+解题思路+代码(2022&2023)

各位置立方和等于本身的三位数

Integer.toBinaryString()的源代码解析

颜色模式中8位,16位,24位,32位色彩是啥意思