Algorithm 从二进制矩阵中划掉坏行

Algorithm 从二进制矩阵中划掉坏行,algorithm,matrix,Algorithm,Matrix,我们得到了n边的平方二元矩阵。 我们将考虑包含至少一个0作为“坏”的任何行或列。 任务是清空所有错误的行和列。 任务需要使用0(1)个额外内存 1 1 0 0 0 0 1 1 1 => 1 0 0 1 0 1 0 0 0 困难的是,当我们在遍历过程中发现坏线时,我们不能将它们置零(否则,我们将始终以零矩阵结束)。所以我在寻找这样一种数据结构或数据表示方式,这样它可以在算法在矩阵中迭代时存储关于坏行和坏列的所有信息。实际上,我们只需要2n位就可以得到答案:我们需要知道每一

我们得到了n边的平方二元矩阵。
我们将考虑包含至少一个0作为“坏”的任何行或列。 任务是清空所有错误的行和列。
任务需要使用0(1)个额外内存

1 1 0     0 0 0
1 1 1  => 1 0 0
1 0 1     0 0 0

困难的是,当我们在遍历过程中发现坏线时,我们不能将它们置零(否则,我们将始终以零矩阵结束)。所以我在寻找这样一种数据结构或数据表示方式,这样它可以在算法在矩阵中迭代时存储关于坏行和坏列的所有信息。

实际上,我们只需要2n位就可以得到答案:我们需要知道每一行和列是好(1)还是坏(0)。每个单元格中的答案将是行和列答案的乘积

让我们将大部分信息存储在矩阵本身中: 我们可以使用第一行为所有列保留记录(0或1),但第一行除外, 第一列保留除第一行以外的所有行的记录,我们还需要两个位来保留第一行和第一列的记录

首先,我们得到这两个额外的位(检查第一行和第一列)

然后查找并存储其他行和列的记录

然后计算除第一行和第列之外的所有矩阵中的结果位


最后:如果第一行不好,则应将其置为空,否则应保持原样,第一列也应如此。

作为第一步,在网格中查找0。如果我们找不到,我们就完了

如果我们找到一个,我们就知道应该使0的行和列中的所有1都为空

因此,由于我们知道所有这些单元格的最终值,我们可以使用该行和该列作为临时布尔标志,来确定同一行或同一列是否包含任何0

确切的过程是:

  • 通过矩阵查找0
  • 跟踪找到的0的坐标
  • 在每行和每列上循环,检查该行或列是否包含0,并适当设置标志
  • 然后再次在矩阵上循环,对于不在标志行或列中的每个1,检查是否设置了行或列标志,如果设置了,则将该1设置为0
  • 然后将行和列中用作标志的所有单元格设置为0
它在线性时间(O(mn)中运行,有m行和n列)和O(1)空间

示例:

输入:

1 1 0 1 0
1 1 1 0 1
1 0 1 1 1
1 1 1 1 1
1 1 1 1 1
然后我们寻找一个零,假设我们找到了顶部中间的一个

然后,我们使用顶行和中间列作为标记,以确定同一行/列是否包含0:

0 1 0 1 1
    1  
    1  
    0  
    0  
然后,如果设置了标志行/列,我们循环其他单元格,将1设置为0:

0 0   0 0
0 0   0 0
1 0   0 0
1 0   0 0
然后我们将标志行和标志列设置为0:

0 0 0 0 0
    0  
    0  
    0  
    0  
然后我们有了最终的输出:

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 0 0 0 0
1 0 0 0 0

<>这显然是在原地进行的,我只是为了直观地把它分开,

< p>我写了C++实现,Natalya Ginzburg有帮助的答案。 把它留在这里,以防对别人有用。

#包括
#包括
#包括
#包括
#包括
#包括
类矩阵{
公众:
矩阵(int n):
侧(n),
步幅(圆形(n/8+1)),
是否很好(正确),
is0ColGood(正确){
printf(“%d%d\n”,侧面,跨步);
数据=新字符[跨步*边];
memset(数据,0,步幅*侧面*大小(字符));
如果(!数据){
printf(“alloc问题”);
出口(1);
}
填充();
打印();
}
~Matrix(){
如果(数据)
删除数据;
}
无效过程(){
对于(int j=0;j#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h> 
#include <unistd.h>

class Matrix {
public:
    Matrix(int n):
            side(n),
            stride( round(n/8+1) ),
            is0RowGood(true),
            is0ColGood(true) {
        printf("%d %d\n", side, stride);
        data = new char[stride*side]; 
        memset(data, 0, stride*side*sizeof(char) );
        if( !data ) {
            printf("alloc problem\n");
            exit(1);
        }
        fill();
        print();
    }

    ~Matrix() {
        if(data)
            delete data;
    }

    void process() {
        for( int j = 0; j < side; ++j ) {
            if(getEl(0, j) == false) {
                is0RowGood = false;
                break;
            }
        }
        for( int i = 0; i < side; ++i ) {
           if(getEl(i, 0) == false) {
                is0ColGood = false;
                break;
            }
        }

        for( int i = 1; i < side; ++i ) {
            for( int j = 1; j < side; ++j ) {
                if(!getEl(i,j)) {
                    setEl(i,0, false);
                    break;
                }
            }
        }

        for( int j = 1; j < side; ++j ) {
            for( int i = 1; i < side; ++i ) {
                if(!getEl(j,i)) {
                    setEl(0, i, false); 
                    break;
                }
            }
        }
        // nullify now
        for( int i = 1; i < side; ++i ) {
            for( int j = 1; j < side; ++j ) {
                if( !getEl(0,j) || !getEl(i,0) )
                {
                    crossRow(i);
                    crossCol(j);
                }
            }
        }

        if(!is0RowGood)
            crossRow(0);
        if(!is0ColGood)
            crossCol(0);

        printf("--\n");
        print();
    }

private:
    void crossRow(int x) {
        for(int i = 0; i < side; ++i ) {
            setEl(x, i, false);
        }
    }

    void crossCol(int x) {
        for(int i = 0; i < side; ++i ) {
            setEl(i, x, false);
        }
    }

    void print() {
        for( int i = 0; i < side; ++i ) {
            for( int j = 0; j < side; ++j ) {
                printf(" %d ", getEl(i,j));
            }
            printf("\n");
        }
    }

    void fill() {
        for( int i = 0; i < side; ++i ) {
            for( int j = 0; j < side; ++j ) {
                usleep(15);
                setEl(i, j, (rand() % 30 == 0) ? 0 : 1);
            }
        }
    }



    bool getEl(int i, int j) {
        int offset = trunc(i/8) + j*stride;
        char byte = data[offset];
        return byte & static_cast<char>(pow(2, i%8));
    }

    bool setEl(int i, int j, bool val) {
        int offset = trunc(i/8) + j*stride;
        if(val)
            data[offset] |= static_cast<char>(pow(2, i%8));
        else
            data[offset] &= static_cast<char>(255-pow(2, i%8));

    }

    bool is0RowGood;
    bool is0ColGood;
    char* data;
    int side;
    int stride;
};

int
main( int argc,
      const char** argv ) {
    if(argc < 2) {
        printf("give n as arg\n");
        exit(1);
    }
    time_t t;
    if(argc == 3)
        t = atoi(argv[2]);
    else {
     t = time(NULL);
     printf("t=%d",t);
    }
    srand (t);
    int n = atoi( argv[1] );
    printf("n=%d\n",n);
    Matrix m(n);
    m.process();
}