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

问题描述 投票:-1回答:2

给出了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}  

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

binary bit-manipulation
2个回答
0
投票

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

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

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
}

0
投票

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

要转置加法,请使用计数器数组,但不是为每个位置使用一个计数器,我们将为计数的每个位使用一个计数器。因此,一个计数器跟踪每个位置是否计数是偶数/奇数,一个计数器跟踪每个位置是否计数中有一个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位。

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

© www.soinside.com 2019 - 2024. All rights reserved.