如何有效地为每个i和j执行[i& j] + = b [i] * c [j]?

时间:2017-12-22 02:29:19

标签: bit-manipulation bitmask

我有两个整数数组bc,大小小于1024.我想有效地找到一个新数组a,这样我就可以a[i&j] += b[i] * c[j]每0 <= i,j <= 1024.我正在寻找除常规O(n ^ 2)以外的解决方案。

基本上我希望改进这个:

for(int i = 0; i < 1024; ++i){
   for(int j = 0; j < 1024; ++j){
      a[i&j] += b[i] * c[j];
   }
}

1 个答案:

答案 0 :(得分:1)

我害怕不。由于您要为b[i]c[j]每个可能的组合添加ij,因此您必须遍历所有这些组合。但是,你可以改进的很少。

如果您只需要特定的a[n],而不是整个数组a,那么这是一种更好的方法。

int n = 666; // Input
// Split input into bits
int e[10] = {};
for (int i = 0, ne = 0; i < 10; i++) {
    if ((n & (1<<i)) == 0)
        e[ne++] = i; // Store the indices of zero bits of input
}

现在从输入中创建b[i]c[j]

int i, j;
// Enumerate all possible combinations of i and j
for (int count = 0; count < pow(3, ne); count++){
    int t = count;
    i = j = 0;
    for (int k = 0; k < ne; k++) {
        switch (t % 3) {
            case 0: break;
            case 1:
                i |= 1 << k;
                break;
            case 2:
                j |= 1 << k;
                break;
        }
        t /= 3;
    }
    i |= n, j |= n;
    a[n] += b[i] * c[j];
}