C++ 大矩阵的子矩阵和

C++ 大矩阵的子矩阵和,c++,c,matrix,submatrix,C++,C,Matrix,Submatrix,我有一个大矩阵作为输入,我有一个小矩阵的大小。我必须计算所有可能的较小矩阵的和,这些矩阵可以由较大的矩阵组成 例如。 输入矩阵大小:4×4 矩阵: 1 2 3 4 5 6 7 8 9 9 0 0 0 0 9 9 输入较小的矩阵大小:3×3(不一定是正方形) 可能更小的矩阵: 1 2 3 5 6 7 9 9 0 5 6 7 9 9 0 0 0 9 2 3 4 6 7 8 9 0 0 6 7 8 9 0 0 0 9 9 他们的总和,最终的产出 14 18 22 29 22 15 18 18

我有一个大矩阵作为输入,我有一个小矩阵的大小。我必须计算所有可能的较小矩阵的和,这些矩阵可以由较大的矩阵组成

例如。 输入矩阵大小:4×4

矩阵:

1 2 3 4
5 6 7 8
9 9 0 0
0 0 9 9
输入较小的矩阵大小:3×3(不一定是正方形)

可能更小的矩阵:

1 2 3
5 6 7
9 9 0

5 6 7
9 9 0
0 0 9

2 3 4
6 7 8
9 0 0

6 7 8
9 0 0
0 9 9
他们的总和,最终的产出

14 18 22
29 22 15
18 18 18
我这样做:

int** matrix_sum(int **M, int n, int r, int c)
{
    int **res = new int*[r];
    for(int i=0 ; i<r ; i++) {
        res[i] = new int[c];
        memset(res[i], 0, sizeof(int)*c);
    }

    for(int i=0 ; i<=n-r ; i++)
    for(int j=0 ; j<=n-c ; j++)
    for(int k=i ; k<i+r ; k++)
    for(int l=j ; l<j+c ; l++)
    res[k-i][l-j] += M[k][l];

    return res;
}
int**matrix\u sum(int**M,int n,int r,int c)
{
整数**res=新整数*[r];

对于(inti=0;i您当前的算法是O((m-p)*(n-q)*p*q)。最坏的情况是当p=m/2和q=n/2时

我将要描述的算法是O(m*n+p*q),它将是O(m*n),与p和q无关

该算法由两个步骤组成

让输入矩阵A的大小为
mxn
,窗口矩阵的大小为
pxq

首先,您将创建一个与输入矩阵大小相同的预计算矩阵B。预计算矩阵B的每个元素包含子矩阵中所有元素的总和,其左上角元素位于坐标(1,1)处原始矩阵的,右下角的元素和我们计算的元素在同一个坐标上

B[i, j] = Sum[k = 1..i, l = 1..j]( A[k, l] ) for all 1 <= i <= m, 1 <= j <= n
然后,第二步是计算结果矩阵S,其大小为
pxq
。如果进行观察,S[i,j]是矩阵大小(m-p+1)*(n-q+1)中所有元素的总和,其左上角坐标为(i,j),右下角坐标为(i+m-p+1,j+n-q+1)

使用预计算的矩阵B,您可以计算O(1)中任何子矩阵的和。将其应用于计算结果矩阵S:

SubMatrixSum(top-left = (x1, y1), bottom-right = (x2, y2))
     = B[x2, y2] - B[x1 - 1, y2] - B[x2, y1 - 1] + B[x1 - 1, y1 - 1]
因此,第二步骤的复杂度将是O(p×q)


最后的复杂度如上所述,O(m*n),因为p,在实现之后,您可以检查这个问题中的算法,
int**m
B[i, j] = B[i - 1, j] + B[i, j - 1] - B[i - 1, j - 1] + A[j] for all 1 <= i <= m, 1 <= j <= n and invalid entry = 0
SubMatrixSum(top-left = (x1, y1), bottom-right = (x2, y2))
     = B[x2, y2] - B[x1 - 1, y2] - B[x2, y1 - 1] + B[x1 - 1, y1 - 1]